1use gltf_v1_derive::Validate;
2use serde::de;
3use serde::{Deserialize, Serialize};
4use std::fmt;
5
6use crate::StringIndex;
7use crate::validation::USize64;
8
9use super::validation::Checked;
10
11pub const ARRAY_BUFFER: u32 = 34_962;
13
14pub const ELEMENT_ARRAY_BUFFER: u32 = 34_963;
16
17pub const ARRAY_BUFFER_TYPE: &str = "arraybuffer";
18
19pub const TEXT_TYPE: &str = "text";
20
21#[derive(Clone, Copy, Debug, Eq, PartialEq, Default)]
22pub enum BufferType {
23 #[default]
24 ArrayBuffer,
25 Text,
26}
27
28impl BufferType {
29 pub const VALID_TYPES: &[&str] = &[ARRAY_BUFFER_TYPE, TEXT_TYPE];
30}
31
32impl TryFrom<&str> for BufferType {
33 type Error = ();
34
35 fn try_from(value: &str) -> Result<Self, Self::Error> {
36 match value {
37 ARRAY_BUFFER_TYPE => Ok(BufferType::ArrayBuffer),
38 TEXT_TYPE => Ok(BufferType::Text),
39 _ => Err(()),
40 }
41 }
42}
43
44impl From<BufferType> for &str {
45 fn from(value: BufferType) -> Self {
46 match value {
47 BufferType::ArrayBuffer => ARRAY_BUFFER_TYPE,
48 BufferType::Text => TEXT_TYPE,
49 }
50 }
51}
52
53impl Serialize for BufferType {
54 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
55 where
56 S: serde::Serializer,
57 {
58 serializer.serialize_str((*self).into())
59 }
60}
61
62impl<'de> Deserialize<'de> for Checked<BufferType> {
63 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
64 where
65 D: serde::Deserializer<'de>,
66 {
67 struct Visitor;
68 impl serde::de::Visitor<'_> for Visitor {
69 type Value = Checked<BufferType>;
70
71 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
72 write!(f, "any of: {:?}", BufferType::VALID_TYPES)
73 }
74
75 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
76 where
77 E: de::Error,
78 {
79 Ok(value
80 .try_into()
81 .map(Checked::Valid)
82 .unwrap_or(Checked::Invalid))
83 }
84 }
85 deserializer.deserialize_str(Visitor)
86 }
87}
88
89#[derive(Clone, Copy, Debug, Eq, PartialEq, Default)]
90pub enum BufferViewType {
91 #[default]
92 ArrayBuffer,
93 ElementArrayBuffer,
94}
95
96impl BufferViewType {
97 pub const VALID_TARGETS: &[u32] = &[ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER];
98}
99
100impl TryFrom<u32> for BufferViewType {
101 type Error = ();
102
103 fn try_from(value: u32) -> Result<Self, Self::Error> {
104 match value {
105 ARRAY_BUFFER => Ok(BufferViewType::ArrayBuffer),
106 ELEMENT_ARRAY_BUFFER => Ok(BufferViewType::ElementArrayBuffer),
107 _ => Err(()),
108 }
109 }
110}
111
112impl From<BufferViewType> for u32 {
113 fn from(value: BufferViewType) -> Self {
114 match value {
115 BufferViewType::ArrayBuffer => ARRAY_BUFFER,
116 BufferViewType::ElementArrayBuffer => ELEMENT_ARRAY_BUFFER,
117 }
118 }
119}
120
121impl Serialize for BufferViewType {
122 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
123 where
124 S: serde::Serializer,
125 {
126 serializer.serialize_u32((*self).into())
127 }
128}
129
130impl<'de> Deserialize<'de> for Checked<BufferViewType> {
131 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
132 where
133 D: serde::Deserializer<'de>,
134 {
135 struct Visitor;
136 impl serde::de::Visitor<'_> for Visitor {
137 type Value = Checked<BufferViewType>;
138
139 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
140 write!(f, "any of: {:?}", BufferViewType::VALID_TARGETS)
141 }
142
143 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
144 where
145 E: de::Error,
146 {
147 Ok((value as u32)
148 .try_into()
149 .map(Checked::Valid)
150 .unwrap_or(Checked::Invalid))
151 }
152 }
153 deserializer.deserialize_u64(Visitor)
154 }
155}
156
157#[derive(Clone, Debug, serde_derive::Deserialize, serde_derive::Serialize, Validate)]
158pub struct Buffer {
159 pub uri: String,
160 #[serde(rename = "byteLength")]
161 pub byte_length: USize64,
162 #[serde(rename = "type")]
163 pub type_: Option<Checked<BufferType>>,
164 #[serde(skip_serializing_if = "Option::is_none")]
165 pub name: Option<String>,
166}
167
168#[derive(Clone, Debug, serde_derive::Deserialize, serde_derive::Serialize, Validate)]
169pub struct BufferView {
170 pub buffer: StringIndex<Buffer>,
171 #[serde(rename = "byteOffset")]
172 pub byte_offset: USize64,
173 #[serde(
174 rename = "byteLength",
175 skip_serializing_if = "is_default_byte_length",
176 default = "default_byte_length"
177 )]
178 pub byte_length: USize64,
179 #[serde(skip_serializing_if = "Option::is_none")]
180 pub target: Option<Checked<BufferViewType>>,
181 #[serde(skip_serializing_if = "Option::is_none")]
182 pub name: Option<String>,
183}
184
185fn is_default_byte_length(value: &USize64) -> bool {
186 value.0 == 0u64
187}
188
189fn default_byte_length() -> USize64 {
190 0u64.into()
191}
192
193#[test]
194fn test_buffer_deserialize() {
195 let data = r#"{
196 "uri": "vertices.bin",
197 "byteLength": 1024,
198 "name": "user-defined buffer name",
199 "type": "arraybuffer",
200 "extensions" : {
201 "extension_name" : {
202 "extension specific" : "value"
203 }
204 },
205 "extras" : {
206 "Application specific" : "The extra object can contain any properties."
207 }
208 }"#;
209 let buffer: Result<Buffer, _> = serde_json::from_str(data);
210 let buffer_unwrap = buffer.unwrap();
211 println!("{}", serde_json::to_string(&buffer_unwrap).unwrap());
212 assert_eq!("vertices.bin".to_string(), buffer_unwrap.uri);
213}
214
215#[test]
216fn test_binary_buffer_deserialize() {
217 let data = r#"{
218 "type":"arraybuffer",
219 "byteLength":1975367,
220 "uri":"data:,"
221 }"#;
222 let buffer: Result<Buffer, _> = serde_json::from_str(data);
223 let buffer_unwrap = buffer.unwrap();
224 println!("{}", serde_json::to_string(&buffer_unwrap).unwrap());
225 assert_eq!(
226 Some(Checked::Valid(BufferType::ArrayBuffer)),
227 buffer_unwrap.type_
228 );
229}
230
231#[test]
232fn test_buffer_view_deserialize() {
233 let data = r#"{
234 "buffer" : "buffer_id",
235 "byteLength": 76768,
236 "byteOffset": 0,
237 "name": "user-defined name of bufferView with vertices",
238 "target": 34962,
239 "extensions" : {
240 "extension_name" : {
241 "extension specific" : "value"
242 }
243 },
244 "extras" : {
245 "Application specific" : "The extra object can contain any properties."
246 }
247 }"#;
248 let buffer_view: Result<BufferView, _> = serde_json::from_str(data);
249 let buffer_view_unwrap = buffer_view.unwrap();
250 println!("{}", serde_json::to_string(&buffer_view_unwrap).unwrap());
251 assert_eq!(
252 Some("user-defined name of bufferView with vertices".to_string()),
253 buffer_view_unwrap.name
254 );
255}