1use std::fmt;
2
3use gltf_v1_derive::Validate;
4use serde::{de, ser};
5use serde_derive::{Deserialize, Serialize};
6
7use super::{buffer::BufferView, common::StringIndex, validation::Checked};
8
9pub const BYTE: u32 = 5120;
11
12pub const UNSIGNED_BYTE: u32 = 5121;
14
15pub const SHORT: u32 = 5122;
17
18pub const UNSIGNED_SHORT: u32 = 5123;
20
21pub const UNSIGNED_INT: u32 = 5125;
23
24pub const FLOAT: u32 = 5126;
26
27#[repr(u8)]
28#[derive(Clone, Copy, Debug, Eq, PartialEq)]
29pub enum ComponentType {
30 Byte,
31 UnsignedByte,
32 Short,
33 UnsignedShort,
34 UnsignedInt,
35 Float,
36}
37
38impl ComponentType {
39 pub const fn size(&self) -> u32 {
40 match self {
41 ComponentType::Byte | ComponentType::UnsignedByte => 1,
42 ComponentType::Short | ComponentType::UnsignedShort => 2,
43 ComponentType::UnsignedInt | ComponentType::Float => 4,
44 }
45 }
46
47 pub const VALID_COMPONENT_TYPES: &[u32] = &[
48 BYTE,
49 UNSIGNED_BYTE,
50 SHORT,
51 UNSIGNED_SHORT,
52 UNSIGNED_INT,
53 FLOAT,
54 ];
55}
56
57impl From<ComponentType> for u32 {
58 fn from(value: ComponentType) -> Self {
59 match value {
60 ComponentType::Byte => BYTE,
61 ComponentType::UnsignedByte => UNSIGNED_BYTE,
62 ComponentType::Short => SHORT,
63 ComponentType::UnsignedShort => UNSIGNED_SHORT,
64 ComponentType::UnsignedInt => UNSIGNED_INT,
65 ComponentType::Float => FLOAT,
66 }
67 }
68}
69
70impl TryFrom<u32> for ComponentType {
71 type Error = ();
72
73 fn try_from(value: u32) -> Result<Self, Self::Error> {
74 match value {
75 BYTE => Ok(Self::Byte),
76 UNSIGNED_BYTE => Ok(Self::UnsignedByte),
77 SHORT => Ok(Self::Short),
78 UNSIGNED_SHORT => Ok(Self::UnsignedShort),
79 UNSIGNED_INT => Ok(Self::UnsignedInt),
80 FLOAT => Ok(Self::Float),
81 _ => Err(()),
82 }
83 }
84}
85
86impl ser::Serialize for ComponentType {
87 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
88 where
89 S: ser::Serializer,
90 {
91 serializer.serialize_u32(Into::into(*self))
92 }
93}
94
95impl<'de> de::Deserialize<'de> for Checked<ComponentType> {
96 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
97 where
98 D: de::Deserializer<'de>,
99 {
100 struct Visitor;
101 impl de::Visitor<'_> for Visitor {
102 type Value = Checked<ComponentType>;
103
104 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
105 write!(f, "any of: {:?}", ComponentType::VALID_COMPONENT_TYPES)
106 }
107
108 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
109 where
110 E: de::Error,
111 {
112 Ok(TryInto::try_into(value as u32)
113 .map(Checked::Valid)
114 .unwrap_or(Checked::Invalid))
115 }
116 }
117 deserializer.deserialize_u64(Visitor)
118 }
119}
120
121#[derive(Clone, Copy, Debug, Eq, PartialEq)]
122pub enum Type {
123 SCALAR,
124 VEC2,
125 VEC3,
126 VEC4,
127 MAT2,
128 MAT3,
129 MAT4,
130}
131
132impl Type {
133 pub const fn get_num_components(&self) -> u32 {
134 match self {
135 Type::SCALAR => 1,
136 Type::VEC2 => 2,
137 Type::VEC3 => 3,
138 Type::VEC4 => 4,
139 Type::MAT2 => 4,
140 Type::MAT3 => 9,
141 Type::MAT4 => 16,
142 }
143 }
144 pub const VALID_ACCESSOR_TYPES: &[&str] =
145 &["SCALAR", "VEC2", "VEC3", "VEC4", "MAT2", "MAT3", "MAT4"];
146}
147
148impl TryFrom<&str> for Type {
149 type Error = ();
150
151 fn try_from(value: &str) -> Result<Self, Self::Error> {
152 match value {
153 "SCALAR" => Ok(Type::SCALAR),
154 "VEC2" => Ok(Type::VEC2),
155 "VEC3" => Ok(Type::VEC3),
156 "VEC4" => Ok(Type::VEC4),
157 "MAT2" => Ok(Type::MAT2),
158 "MAT3" => Ok(Type::MAT3),
159 "MAT4" => Ok(Type::MAT4),
160 _ => Err(()),
161 }
162 }
163}
164
165impl From<Type> for &str {
166 fn from(value: Type) -> Self {
167 match value {
168 Type::SCALAR => "SCALAR",
169 Type::VEC2 => "VEC2",
170 Type::VEC3 => "VEC3",
171 Type::VEC4 => "VEC4",
172 Type::MAT2 => "MAT2",
173 Type::MAT3 => "MAT3",
174 Type::MAT4 => "MAT4",
175 }
176 }
177}
178
179impl ser::Serialize for Type {
180 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
181 where
182 S: ser::Serializer,
183 {
184 serializer.serialize_str((*self).into())
185 }
186}
187
188impl<'de> de::Deserialize<'de> for Checked<Type> {
189 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
190 where
191 D: de::Deserializer<'de>,
192 {
193 struct Visitor;
194 impl de::Visitor<'_> for Visitor {
195 type Value = Checked<Type>;
196
197 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
198 write!(f, "any of: {:?}", Type::VALID_ACCESSOR_TYPES)
199 }
200
201 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
202 where
203 E: de::Error,
204 {
205 Ok(value
206 .try_into()
207 .map(Checked::Valid)
208 .unwrap_or(Checked::Invalid))
209 }
210 }
211 deserializer.deserialize_str(Visitor)
212 }
213}
214
215#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
216pub struct Accessor {
217 #[serde(rename = "bufferView")]
218 pub buffer_view: StringIndex<BufferView>,
219 #[serde(rename = "byteOffset")]
220 pub byte_offset: u32,
221 #[serde(rename = "byteStride", skip_serializing_if = "Option::is_none")]
222 pub byte_stride: Option<u32>,
223 #[serde(rename = "componentType")]
224 pub component_type: Checked<ComponentType>,
225 pub count: u32,
226 #[serde(rename = "type")]
227 pub type_: Checked<Type>,
228 #[serde(default)]
229 #[serde(skip_serializing_if = "Vec::is_empty")]
230 pub max: Vec<f32>,
231 #[serde(default)]
232 #[serde(skip_serializing_if = "Vec::is_empty")]
233 pub min: Vec<f32>,
234 #[serde(skip_serializing_if = "Option::is_none")]
235 pub name: Option<String>,
236}
237
238#[test]
239fn test_accessor_deserialize() {
240 let data = r#"{
241 "bufferView" : "bufferViewWithVertices_id",
242 "byteOffset" : 0,
243 "byteStride" : 3,
244 "componentType" : 5126,
245 "count" : 1024,
246 "type" : "SCALAR",
247 "name": "user-defined accessor name",
248 "max" : [-1.0, -1.0, -1.0],
249 "min" : [1.0, 1.0, 1.0],
250 "extensions" : {
251 "extension_name" : {
252 "extension specific" : "value"
253 }
254 },
255 "extras" : {
256 "Application specific" : "The extra object can contain any properties."
257 }
258 }
259 "#;
260 let accessor: Result<Accessor, _> = serde_json::from_str(data);
261 let accessor_unwrap = accessor.unwrap();
262 println!("{}", serde_json::to_string(&accessor_unwrap).unwrap());
263 assert_eq!(
264 Some("user-defined accessor name".to_string()),
265 accessor_unwrap.name
266 );
267}