use crate::validation::{Checked, Error, USize64, Validate};
use crate::{extensions, Extras, Index, Path, Root};
use gltf_derive::Validate;
use serde::{de, ser};
use serde_derive::{Deserialize, Serialize};
use std::fmt;
pub const ARRAY_BUFFER: u32 = 34_962;
pub const ELEMENT_ARRAY_BUFFER: u32 = 34_963;
pub const MIN_BYTE_STRIDE: usize = 4;
pub const MAX_BYTE_STRIDE: usize = 252;
pub const VALID_TARGETS: &[u32] = &[ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER];
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Target {
ArrayBuffer = 1,
ElementArrayBuffer,
}
impl ser::Serialize for Target {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: ser::Serializer,
{
match *self {
Target::ArrayBuffer => serializer.serialize_u32(ARRAY_BUFFER),
Target::ElementArrayBuffer => serializer.serialize_u32(ELEMENT_ARRAY_BUFFER),
}
}
}
#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub struct Stride(pub usize);
impl Validate for Stride {
fn validate<P, R>(&self, _root: &Root, path: P, report: &mut R)
where
P: Fn() -> Path,
R: FnMut(&dyn Fn() -> Path, Error),
{
if self.0 < MIN_BYTE_STRIDE || self.0 > MAX_BYTE_STRIDE {
report(&path, Error::Invalid);
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
pub struct Buffer {
#[serde(default, rename = "byteLength")]
pub byte_length: USize64,
#[cfg(feature = "names")]
#[cfg_attr(feature = "names", serde(skip_serializing_if = "Option::is_none"))]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub uri: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub extensions: Option<extensions::buffer::Buffer>,
#[serde(default)]
#[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
#[cfg_attr(not(feature = "extras"), serde(skip_serializing))]
pub extras: Extras,
}
#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
pub struct View {
pub buffer: Index<Buffer>,
#[serde(rename = "byteLength")]
pub byte_length: USize64,
#[serde(
default,
rename = "byteOffset",
skip_serializing_if = "Option::is_none"
)]
pub byte_offset: Option<USize64>,
#[serde(rename = "byteStride")]
#[serde(skip_serializing_if = "Option::is_none")]
pub byte_stride: Option<Stride>,
#[cfg(feature = "names")]
#[cfg_attr(feature = "names", serde(skip_serializing_if = "Option::is_none"))]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub target: Option<Checked<Target>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub extensions: Option<extensions::buffer::View>,
#[serde(default)]
#[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
#[cfg_attr(not(feature = "extras"), serde(skip_serializing))]
pub extras: Extras,
}
impl<'de> de::Deserialize<'de> for Checked<Target> {
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<Target>;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "any of: {:?}", VALID_TARGETS)
}
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
where
E: de::Error,
{
use self::Target::*;
use crate::validation::Checked::*;
Ok(match value as u32 {
ARRAY_BUFFER => Valid(ArrayBuffer),
ELEMENT_ARRAY_BUFFER => Valid(ElementArrayBuffer),
_ => Invalid,
})
}
}
deserializer.deserialize_u64(Visitor)
}
}