use serde::de;
use std::fmt;
use validation::Checked;
use {extensions, image, Extras, Index};
pub const NEAREST: u32 = 9728;
pub const LINEAR: u32 = 9729;
pub const NEAREST_MIPMAP_NEAREST: u32 = 9984;
pub const LINEAR_MIPMAP_NEAREST: u32 = 9985;
pub const NEAREST_MIPMAP_LINEAR: u32 = 9986;
pub const LINEAR_MIPMAP_LINEAR: u32 = 9987;
pub const CLAMP_TO_EDGE: u32 = 33071;
pub const MIRRORED_REPEAT: u32 = 33648;
pub const REPEAT: u32 = 10497;
pub const VALID_MAG_FILTERS: &'static [u32] = &[
NEAREST,
LINEAR,
];
pub const VALID_MIN_FILTERS: &'static [u32] = &[
NEAREST,
LINEAR,
NEAREST_MIPMAP_NEAREST,
LINEAR_MIPMAP_NEAREST,
NEAREST_MIPMAP_LINEAR,
LINEAR_MIPMAP_LINEAR,
];
pub const VALID_WRAPPING_MODES: &'static [u32] = &[
CLAMP_TO_EDGE,
MIRRORED_REPEAT,
REPEAT,
];
#[derive(Clone, Copy, Debug, Deserialize)]
pub enum MagFilter {
Nearest = 1,
Linear,
}
impl MagFilter {
pub fn as_gl_enum(&self) -> i32 {
match *self {
MagFilter::Nearest => NEAREST as i32,
MagFilter::Linear => LINEAR as i32,
}
}
}
#[derive(Clone, Copy, Debug, Deserialize)]
pub enum MinFilter {
Nearest = 1,
Linear,
NearestMipmapNearest,
LinearMipmapNearest,
NearestMipmapLinear,
LinearMipmapLinear,
}
impl MinFilter {
pub fn as_gl_enum(&self) -> i32 {
match *self {
MinFilter::Nearest => NEAREST as i32,
MinFilter::Linear => LINEAR as i32,
MinFilter::NearestMipmapNearest => NEAREST_MIPMAP_NEAREST as i32,
MinFilter::LinearMipmapNearest => LINEAR_MIPMAP_NEAREST as i32,
MinFilter::NearestMipmapLinear => NEAREST_MIPMAP_LINEAR as i32,
MinFilter::LinearMipmapLinear => LINEAR_MIPMAP_LINEAR as i32,
}
}
}
#[derive(Clone, Copy, Debug, Deserialize)]
pub enum WrappingMode {
ClampToEdge = 1,
MirroredRepeat,
Repeat,
}
impl WrappingMode {
pub fn as_gl_enum(&self) -> i32 {
match *self {
WrappingMode::ClampToEdge => CLAMP_TO_EDGE as i32,
WrappingMode::MirroredRepeat => MIRRORED_REPEAT as i32,
WrappingMode::Repeat => REPEAT as i32,
}
}
}
#[derive(Clone, Debug, Default, Deserialize, Validate)]
#[serde(default)]
pub struct Sampler {
#[serde(rename = "magFilter")]
pub mag_filter: Option<Checked<MagFilter>>,
#[serde(rename = "minFilter")]
pub min_filter: Option<Checked<MinFilter>>,
#[cfg(feature = "names")]
pub name: Option<String>,
#[serde(default, rename = "wrapS")]
pub wrap_s: Checked<WrappingMode>,
#[serde(default, rename = "wrapT")]
pub wrap_t: Checked<WrappingMode>,
#[serde(default)]
pub extensions: extensions::texture::Sampler,
#[serde(default)]
pub extras: Extras,
}
#[derive(Clone, Debug, Deserialize, Validate)]
pub struct Texture {
#[cfg(feature = "names")]
pub name: Option<String>,
pub sampler: Option<Index<Sampler>>,
pub source: Index<image::Image>,
#[serde(default)]
pub extensions: extensions::texture::Texture,
#[serde(default)]
pub extras: Extras,
}
#[derive(Clone, Debug, Deserialize, Validate)]
pub struct Info {
pub index: Index<Texture>,
#[serde(default, rename = "texCoord")]
pub tex_coord: u32,
#[serde(default)]
pub extensions: extensions::texture::Info,
#[serde(default)]
pub extras: Extras,
}
impl<'de> de::Deserialize<'de> for Checked<MagFilter> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: de::Deserializer<'de>
{
struct Visitor;
impl<'de> de::Visitor<'de> for Visitor {
type Value = Checked<MagFilter>;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "any of: {:?}", VALID_MAG_FILTERS)
}
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
where E: de::Error
{
use self::MagFilter::*;
use validation::Checked::*;
Ok(match value as u32 {
NEAREST => Valid(Nearest),
LINEAR => Valid(Linear),
_ => Invalid,
})
}
}
deserializer.deserialize_u64(Visitor)
}
}
impl<'de> de::Deserialize<'de> for Checked<MinFilter> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: de::Deserializer<'de>
{
struct Visitor;
impl<'de> de::Visitor<'de> for Visitor {
type Value = Checked<MinFilter>;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "any of: {:?}", VALID_MIN_FILTERS)
}
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
where E: de::Error
{
use self::MinFilter::*;
use validation::Checked::*;
Ok(match value as u32 {
NEAREST => Valid(Nearest),
LINEAR => Valid(Linear),
NEAREST_MIPMAP_NEAREST => Valid(NearestMipmapNearest),
LINEAR_MIPMAP_NEAREST => Valid(LinearMipmapNearest),
NEAREST_MIPMAP_LINEAR => Valid(NearestMipmapLinear),
LINEAR_MIPMAP_LINEAR => Valid(LinearMipmapLinear),
_ => Invalid,
})
}
}
deserializer.deserialize_u64(Visitor)
}
}
impl<'de> de::Deserialize<'de> for Checked<WrappingMode> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: de::Deserializer<'de>
{
struct Visitor;
impl<'de> de::Visitor<'de> for Visitor {
type Value = Checked<WrappingMode>;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "any of: {:?}", VALID_WRAPPING_MODES)
}
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
where E: de::Error
{
use self::WrappingMode::*;
use validation::Checked::*;
Ok(match value as u32 {
CLAMP_TO_EDGE => Valid(ClampToEdge),
MIRRORED_REPEAT => Valid(MirroredRepeat),
REPEAT => Valid(Repeat),
_ => Invalid,
})
}
}
deserializer.deserialize_u64(Visitor)
}
}
impl Default for WrappingMode {
fn default() -> Self {
WrappingMode::Repeat
}
}