1use crate::validation::{Checked, Error, Validate};
2use crate::{extensions, Index, Path, Root};
3use serde::{de, ser};
4use serde_derive::{Deserialize, Serialize};
5use shine_gltf_macro::Validate;
6use std::fmt;
7
8pub const ARRAY_BUFFER: u32 = 34_962;
10
11pub const ELEMENT_ARRAY_BUFFER: u32 = 34_963;
13
14pub const MIN_BYTE_STRIDE: u32 = 4;
16
17pub const MAX_BYTE_STRIDE: u32 = 252;
19
20pub const VALID_TARGETS: &[u32] = &[ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER];
22
23#[derive(Clone, Copy, Debug, Eq, PartialEq)]
25pub enum Target {
26 ArrayBuffer = 1,
28
29 ElementArrayBuffer,
31}
32
33impl ser::Serialize for Target {
34 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
35 where
36 S: ser::Serializer,
37 {
38 match *self {
39 Target::ArrayBuffer => serializer.serialize_u32(ARRAY_BUFFER),
40 Target::ElementArrayBuffer => serializer.serialize_u32(ELEMENT_ARRAY_BUFFER),
41 }
42 }
43}
44
45#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
47pub struct Buffer {
48 #[serde(default, rename = "byteLength")]
50 pub byte_length: u32,
51
52 #[serde(skip_serializing_if = "Option::is_none")]
55 pub uri: Option<String>,
56
57 #[serde(default, skip_serializing_if = "Option::is_none")]
59 pub extensions: Option<extensions::buffer::Buffer>,
60}
61
62#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
67pub struct View {
68 pub buffer: Index<Buffer>,
70
71 #[serde(rename = "byteLength")]
73 pub byte_length: u32,
74
75 #[serde(default, rename = "byteOffset", skip_serializing_if = "Option::is_none")]
77 pub byte_offset: Option<u32>,
78
79 #[serde(rename = "byteStride")]
83 #[serde(skip_serializing_if = "Option::is_none")]
84 pub byte_stride: Option<ByteStride>,
85
86 #[serde(skip_serializing_if = "Option::is_none")]
88 pub target: Option<Checked<Target>>,
89
90 #[serde(default, skip_serializing_if = "Option::is_none")]
92 pub extensions: Option<extensions::buffer::View>,
93}
94
95impl View {
96 pub fn with_buffer(buffer: Index<Buffer>) -> View {
97 View {
98 buffer,
99 byte_length: 0,
100 byte_offset: None,
101 byte_stride: None,
102 target: None,
103 extensions: None,
104 }
105 }
106}
107
108#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
110pub struct ByteStride(pub u32);
111
112impl Validate for ByteStride {
113 fn validate_completely<P, R>(&self, _: &Root, path: P, report: &mut R)
114 where
115 P: Fn() -> Path,
116 R: FnMut(&dyn Fn() -> Path, Error),
117 {
118 if self.0 % 4 != 0 {
119 report(&path, Error::Invalid);
121 }
122
123 if self.0 < MIN_BYTE_STRIDE || self.0 > MAX_BYTE_STRIDE {
124 report(&path, Error::Invalid);
125 }
126 }
127}
128
129impl<'de> de::Deserialize<'de> for Checked<Target> {
130 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
131 where
132 D: de::Deserializer<'de>,
133 {
134 struct Visitor;
135 impl<'de> de::Visitor<'de> for Visitor {
136 type Value = Checked<Target>;
137
138 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
139 write!(f, "any of: {:?}", VALID_TARGETS)
140 }
141
142 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
143 where
144 E: de::Error,
145 {
146 use self::Target::*;
147 use crate::validation::Checked::*;
148 Ok(match value as u32 {
149 ARRAY_BUFFER => Valid(ArrayBuffer),
150 ELEMENT_ARRAY_BUFFER => Valid(ElementArrayBuffer),
151 _ => Invalid,
152 })
153 }
154 }
155 deserializer.deserialize_u64(Visitor)
156 }
157}