1pub use fyrox_core_derive::Visit;
32
33pub mod prelude {
34 pub use super::{Visit, VisitError, VisitResult, Visitor};
36}
37
38use crate::{
39 algebra::{
40 Complex, Const, Matrix, Matrix2, Matrix3, Matrix4, Quaternion, RawStorage, RawStorageMut,
41 SVector, Scalar, UnitComplex, UnitQuaternion, Vector2, Vector3, Vector4, U1,
42 },
43 array_as_u8_slice_mut,
44 io::{self, FileLoadError},
45 pool::{Handle, Pool},
46 replace_slashes,
47};
48
49use base64::Engine;
50use bitflags::bitflags;
51use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
52use fxhash::FxHashMap;
53use std::any::TypeId;
54use std::error::Error;
55use std::{
56 any::Any,
57 cell::{Cell, RefCell},
58 collections::{hash_map::Entry, HashMap, HashSet},
59 fmt::{Display, Formatter},
60 fs::File,
61 hash::{BuildHasher, Hash},
62 io::{BufWriter, Cursor, Read, Write},
63 ops::{Deref, DerefMut, Range},
64 path::{Path, PathBuf},
65 rc::Rc,
66 string::FromUtf8Error,
67 sync::{Arc, Mutex, RwLock},
68 time::Duration,
69};
70use uuid::Uuid;
71
72pub enum FieldKind {
78 Bool(bool),
79 U8(u8),
80 I8(i8),
81 U16(u16),
82 I16(i16),
83 U32(u32),
84 I32(i32),
85 U64(u64),
86 I64(i64),
87 F32(f32),
88 F64(f64),
89 UnitQuaternion(UnitQuaternion<f32>),
90 Matrix4(Matrix4<f32>),
91 BinaryBlob(Vec<u8>),
94 Matrix3(Matrix3<f32>),
95 Uuid(Uuid),
96 UnitComplex(UnitComplex<f32>),
97 PodArray {
99 type_id: u8,
102 element_size: u32,
104 bytes: Vec<u8>,
106 },
107 Matrix2(Matrix2<f32>),
108
109 Vector2F32(Vector2<f32>),
110 Vector3F32(Vector3<f32>),
111 Vector4F32(Vector4<f32>),
112
113 Vector2F64(Vector2<f64>),
114 Vector3F64(Vector3<f64>),
115 Vector4F64(Vector4<f64>),
116
117 Vector2U8(Vector2<u8>),
118 Vector3U8(Vector3<u8>),
119 Vector4U8(Vector4<u8>),
120
121 Vector2I8(Vector2<i8>),
122 Vector3I8(Vector3<i8>),
123 Vector4I8(Vector4<i8>),
124
125 Vector2U16(Vector2<u16>),
126 Vector3U16(Vector3<u16>),
127 Vector4U16(Vector4<u16>),
128
129 Vector2I16(Vector2<i16>),
130 Vector3I16(Vector3<i16>),
131 Vector4I16(Vector4<i16>),
132
133 Vector2U32(Vector2<u32>),
134 Vector3U32(Vector3<u32>),
135 Vector4U32(Vector4<u32>),
136
137 Vector2I32(Vector2<i32>),
138 Vector3I32(Vector3<i32>),
139 Vector4I32(Vector4<i32>),
140
141 Vector2U64(Vector2<u64>),
142 Vector3U64(Vector3<u64>),
143 Vector4U64(Vector4<u64>),
144
145 Vector2I64(Vector2<i64>),
146 Vector3I64(Vector3<i64>),
147 Vector4I64(Vector4<i64>),
148}
149
150pub trait Pod: Copy {
153 fn type_id() -> u8;
158}
159
160impl Pod for u8 {
161 fn type_id() -> u8 {
162 0
163 }
164}
165
166impl Pod for i8 {
167 fn type_id() -> u8 {
168 1
169 }
170}
171
172impl Pod for u16 {
173 fn type_id() -> u8 {
174 2
175 }
176}
177
178impl Pod for i16 {
179 fn type_id() -> u8 {
180 3
181 }
182}
183
184impl Pod for u32 {
185 fn type_id() -> u8 {
186 4
187 }
188}
189
190impl Pod for i32 {
191 fn type_id() -> u8 {
192 5
193 }
194}
195
196impl Pod for u64 {
197 fn type_id() -> u8 {
198 6
199 }
200}
201
202impl Pod for i64 {
203 fn type_id() -> u8 {
204 7
205 }
206}
207
208impl Pod for f32 {
209 fn type_id() -> u8 {
210 8
211 }
212}
213
214impl Pod for f64 {
215 fn type_id() -> u8 {
216 9
217 }
218}
219
220pub struct PodVecView<'a, T: Pod> {
224 type_id: u8,
225 vec: &'a mut Vec<T>,
226}
227
228impl<'a, T: Pod> PodVecView<'a, T> {
229 pub fn from_pod_vec(vec: &'a mut Vec<T>) -> Self {
230 Self {
231 type_id: T::type_id(),
232 vec,
233 }
234 }
235}
236
237impl<T: Pod> Visit for PodVecView<'_, T> {
238 #[allow(clippy::uninit_vec)]
239 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
240 if visitor.reading {
241 if let Some(field) = visitor.find_field(name) {
242 match &field.kind {
243 FieldKind::PodArray {
244 type_id,
245 element_size,
246 bytes,
247 } => {
248 if *type_id == self.type_id {
249 let len = bytes.len() / *element_size as usize;
250 let mut data = Vec::<T>::with_capacity(len);
251 unsafe {
252 data.set_len(len);
253 std::ptr::copy_nonoverlapping(
254 bytes.as_ptr(),
255 data.as_mut_ptr() as *mut u8,
256 bytes.len(),
257 );
258 }
259 *self.vec = data;
260 Ok(())
261 } else {
262 Err(VisitError::TypeMismatch)
263 }
264 }
265 _ => Err(VisitError::FieldTypeDoesNotMatch),
266 }
267 } else {
268 Err(VisitError::FieldDoesNotExist(name.to_owned()))
269 }
270 } else if visitor.find_field(name).is_some() {
271 Err(VisitError::FieldAlreadyExists(name.to_owned()))
272 } else {
273 let node = visitor.current_node();
274 node.fields.push(Field::new(
275 name,
276 FieldKind::PodArray {
277 type_id: T::type_id(),
278 element_size: std::mem::size_of::<T>() as u32,
279 bytes: unsafe {
280 let mut data = self.vec.clone();
281 let bytes = Vec::from_raw_parts(
282 data.as_mut_ptr() as *mut u8,
283 data.len() * std::mem::size_of::<T>(),
284 data.capacity() * std::mem::size_of::<T>(),
285 );
286 std::mem::forget(data);
287 bytes
288 },
289 },
290 ));
291 Ok(())
292 }
293 }
294}
295
296impl FieldKind {
297 fn as_string(&self) -> String {
298 match self {
299 Self::Bool(data) => format!("<bool = {data}>, "),
300 Self::U8(data) => format!("<u8 = {data}>, "),
301 Self::I8(data) => format!("<i8 = {data}>, "),
302 Self::U16(data) => format!("<u16 = {data}>, "),
303 Self::I16(data) => format!("<i16 = {data}>, "),
304 Self::U32(data) => format!("<u32 = {data}>, "),
305 Self::I32(data) => format!("<i32 = {data}>, "),
306 Self::U64(data) => format!("<u64 = {data}>, "),
307 Self::I64(data) => format!("<i64 = {data}>, "),
308 Self::F32(data) => format!("<f32 = {data}>, "),
309 Self::F64(data) => format!("<f64 = {data}>, "),
310 Self::Vector2F32(data) => format!("<vec2f32 = {}; {}>, ", data.x, data.y),
311 Self::Vector3F32(data) => format!("<vec3f32 = {}; {}; {}>, ", data.x, data.y, data.z),
312 Self::Vector4F32(data) => {
313 format!(
314 "<vec4f32 = {}; {}; {}; {}>, ",
315 data.x, data.y, data.z, data.w
316 )
317 }
318 Self::Vector2F64(data) => format!("<vec2f64 = {}; {}>, ", data.x, data.y),
319 Self::Vector3F64(data) => format!("<vec3f64 = {}; {}; {}>, ", data.x, data.y, data.z),
320 Self::Vector4F64(data) => {
321 format!(
322 "<vec4f64 = {}; {}; {}; {}>, ",
323 data.x, data.y, data.z, data.w
324 )
325 }
326 Self::Vector2I8(data) => format!("<vec2i8 = {}; {}>, ", data.x, data.y),
327 Self::Vector3I8(data) => format!("<vec3i8 = {}; {}; {}>, ", data.x, data.y, data.z),
328 Self::Vector4I8(data) => {
329 format!(
330 "<vec4i8 = {}; {}; {}; {}>, ",
331 data.x, data.y, data.z, data.w
332 )
333 }
334 Self::Vector2U8(data) => format!("<vec2u8 = {}; {}>, ", data.x, data.y),
335 Self::Vector3U8(data) => format!("<vec3u8 = {}; {}; {}>, ", data.x, data.y, data.z),
336 Self::Vector4U8(data) => {
337 format!(
338 "<vec4u8 = {}; {}; {}; {}>, ",
339 data.x, data.y, data.z, data.w
340 )
341 }
342
343 Self::Vector2I16(data) => format!("<vec2i16 = {}; {}>, ", data.x, data.y),
344 Self::Vector3I16(data) => format!("<vec3i16 = {}; {}; {}>, ", data.x, data.y, data.z),
345 Self::Vector4I16(data) => {
346 format!(
347 "<vec4i16 = {}; {}; {}; {}>, ",
348 data.x, data.y, data.z, data.w
349 )
350 }
351 Self::Vector2U16(data) => format!("<vec2u16 = {}; {}>, ", data.x, data.y),
352 Self::Vector3U16(data) => format!("<vec3u16 = {}; {}; {}>, ", data.x, data.y, data.z),
353 Self::Vector4U16(data) => {
354 format!(
355 "<vec4u16 = {}; {}; {}; {}>, ",
356 data.x, data.y, data.z, data.w
357 )
358 }
359
360 Self::Vector2I32(data) => format!("<vec2i32 = {}; {}>, ", data.x, data.y),
361 Self::Vector3I32(data) => format!("<vec3i32 = {}; {}; {}>, ", data.x, data.y, data.z),
362 Self::Vector4I32(data) => {
363 format!(
364 "<vec4i32 = {}; {}; {}; {}>, ",
365 data.x, data.y, data.z, data.w
366 )
367 }
368 Self::Vector2U32(data) => format!("<vec2u32 = {}; {}>, ", data.x, data.y),
369 Self::Vector3U32(data) => format!("<vec3u32 = {}; {}; {}>, ", data.x, data.y, data.z),
370 Self::Vector4U32(data) => {
371 format!(
372 "<vec4u32 = {}; {}; {}; {}>, ",
373 data.x, data.y, data.z, data.w
374 )
375 }
376
377 Self::Vector2I64(data) => format!("<vec2i64 = {}; {}>, ", data.x, data.y),
378 Self::Vector3I64(data) => format!("<vec3i64 = {}; {}; {}>, ", data.x, data.y, data.z),
379 Self::Vector4I64(data) => {
380 format!(
381 "<vec4i64 = {}; {}; {}; {}>, ",
382 data.x, data.y, data.z, data.w
383 )
384 }
385 Self::Vector2U64(data) => format!("<vec2u64 = {}; {}>, ", data.x, data.y),
386 Self::Vector3U64(data) => format!("<vec3u64 = {}; {}; {}>, ", data.x, data.y, data.z),
387 Self::Vector4U64(data) => {
388 format!(
389 "<vec4u64 = {}; {}; {}; {}>, ",
390 data.x, data.y, data.z, data.w
391 )
392 }
393
394 Self::UnitQuaternion(data) => {
395 format!("<quat = {}; {}; {}; {}>, ", data.i, data.j, data.k, data.w)
396 }
397 Self::Matrix4(data) => {
398 let mut out = String::from("<mat4 = ");
399 for f in data.iter() {
400 out += format!("{f}; ").as_str();
401 }
402 out
403 }
404 Self::BinaryBlob(data) => {
405 let out = match String::from_utf8(data.clone()) {
406 Ok(s) => s,
407 Err(_) => base64::engine::general_purpose::STANDARD.encode(data),
408 };
409 format!("<data = {out}>, ")
410 }
411 Self::Matrix3(data) => {
412 let mut out = String::from("<mat3 = ");
413 for f in data.iter() {
414 out += format!("{f}; ").as_str();
415 }
416 out
417 }
418 Self::Uuid(uuid) => {
419 format!("<uuid = {uuid}")
420 }
421 Self::UnitComplex(data) => {
422 format!("<complex = {}; {}>, ", data.re, data.im)
423 }
424 FieldKind::PodArray {
425 type_id,
426 element_size,
427 bytes,
428 } => {
429 let base64_encoded = base64::engine::general_purpose::STANDARD.encode(bytes);
430 format!("<podarray = {type_id}; {element_size}; [{base64_encoded}]>")
431 }
432 Self::Matrix2(data) => {
433 let mut out = String::from("<mat2 = ");
434 for f in data.iter() {
435 out += format!("{f}; ").as_str();
436 }
437 out
438 }
439 }
440 }
441}
442
443macro_rules! impl_field_data {
444 ($type_name:ty, $($kind:tt)*) => {
445 impl Visit for $type_name {
446 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
447 if visitor.reading {
448 if let Some(field) = visitor.find_field(name) {
449 match field.kind {
450 $($kind)*(data) => {
451 *self = data.clone();
452 Ok(())
453 },
454 _ => Err(VisitError::FieldTypeDoesNotMatch)
455 }
456 } else {
457 Err(VisitError::FieldDoesNotExist(name.to_owned()))
458 }
459 } else if visitor.find_field(name).is_some() {
460 Err(VisitError::FieldAlreadyExists(name.to_owned()))
461 } else {
462 let node = visitor.current_node();
463 node.fields.push(Field::new(name, $($kind)*(self.clone())));
464 Ok(())
465 }
466 }
467 }
468 };
469}
470
471pub struct BinaryBlob<'a, T>
478where
479 T: Copy,
480{
481 pub vec: &'a mut Vec<T>,
482}
483
484impl_field_data!(u64, FieldKind::U64);
485impl_field_data!(i64, FieldKind::I64);
486impl_field_data!(u32, FieldKind::U32);
487impl_field_data!(i32, FieldKind::I32);
488impl_field_data!(u16, FieldKind::U16);
489impl_field_data!(i16, FieldKind::I16);
490impl_field_data!(u8, FieldKind::U8);
491impl_field_data!(i8, FieldKind::I8);
492impl_field_data!(f32, FieldKind::F32);
493impl_field_data!(f64, FieldKind::F64);
494impl_field_data!(UnitQuaternion<f32>, FieldKind::UnitQuaternion);
495impl_field_data!(Matrix4<f32>, FieldKind::Matrix4);
496impl_field_data!(bool, FieldKind::Bool);
497impl_field_data!(Matrix3<f32>, FieldKind::Matrix3);
498impl_field_data!(Uuid, FieldKind::Uuid);
499impl_field_data!(UnitComplex<f32>, FieldKind::UnitComplex);
500impl_field_data!(Matrix2<f32>, FieldKind::Matrix2);
501
502impl_field_data!(Vector2<f32>, FieldKind::Vector2F32);
503impl_field_data!(Vector3<f32>, FieldKind::Vector3F32);
504impl_field_data!(Vector4<f32>, FieldKind::Vector4F32);
505
506impl_field_data!(Vector2<f64>, FieldKind::Vector2F64);
507impl_field_data!(Vector3<f64>, FieldKind::Vector3F64);
508impl_field_data!(Vector4<f64>, FieldKind::Vector4F64);
509
510impl_field_data!(Vector2<i8>, FieldKind::Vector2I8);
511impl_field_data!(Vector3<i8>, FieldKind::Vector3I8);
512impl_field_data!(Vector4<i8>, FieldKind::Vector4I8);
513
514impl_field_data!(Vector2<u8>, FieldKind::Vector2U8);
515impl_field_data!(Vector3<u8>, FieldKind::Vector3U8);
516impl_field_data!(Vector4<u8>, FieldKind::Vector4U8);
517
518impl_field_data!(Vector2<i16>, FieldKind::Vector2I16);
519impl_field_data!(Vector3<i16>, FieldKind::Vector3I16);
520impl_field_data!(Vector4<i16>, FieldKind::Vector4I16);
521
522impl_field_data!(Vector2<u16>, FieldKind::Vector2U16);
523impl_field_data!(Vector3<u16>, FieldKind::Vector3U16);
524impl_field_data!(Vector4<u16>, FieldKind::Vector4U16);
525
526impl_field_data!(Vector2<i32>, FieldKind::Vector2I32);
527impl_field_data!(Vector3<i32>, FieldKind::Vector3I32);
528impl_field_data!(Vector4<i32>, FieldKind::Vector4I32);
529
530impl_field_data!(Vector2<u32>, FieldKind::Vector2U32);
531impl_field_data!(Vector3<u32>, FieldKind::Vector3U32);
532impl_field_data!(Vector4<u32>, FieldKind::Vector4U32);
533
534impl_field_data!(Vector2<i64>, FieldKind::Vector2I64);
535impl_field_data!(Vector3<i64>, FieldKind::Vector3I64);
536impl_field_data!(Vector4<i64>, FieldKind::Vector4I64);
537
538impl_field_data!(Vector2<u64>, FieldKind::Vector2U64);
539impl_field_data!(Vector3<u64>, FieldKind::Vector3U64);
540impl_field_data!(Vector4<u64>, FieldKind::Vector4U64);
541
542impl<T> Visit for BinaryBlob<'_, T>
543where
544 T: Copy + bytemuck::Pod,
545{
546 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
547 if visitor.reading {
548 if let Some(field) = visitor.find_field(name) {
549 match &field.kind {
550 FieldKind::BinaryBlob(data) => {
551 let len = data.len() / size_of::<T>();
552 let mut vec = Vec::<T>::with_capacity(len);
553
554 unsafe {
555 std::ptr::copy_nonoverlapping(
556 data.as_ptr(),
557 array_as_u8_slice_mut(&mut vec).as_mut_ptr(),
558 data.len(),
559 );
560
561 vec.set_len(len);
562 }
563
564 *self.vec = vec;
565
566 Ok(())
567 }
568 _ => Err(VisitError::FieldTypeDoesNotMatch),
569 }
570 } else {
571 Err(VisitError::FieldDoesNotExist(name.to_owned()))
572 }
573 } else if visitor.find_field(name).is_some() {
574 Err(VisitError::FieldAlreadyExists(name.to_owned()))
575 } else {
576 let node = visitor.current_node();
577
578 let len_bytes = self.vec.len() * std::mem::size_of::<T>();
579 let mut bytes = Vec::<u8>::with_capacity(len_bytes);
580 bytes.extend_from_slice(unsafe {
581 std::slice::from_raw_parts(self.vec.as_ptr() as *const u8, len_bytes)
582 });
583
584 node.fields
585 .push(Field::new(name, FieldKind::BinaryBlob(bytes)));
586
587 Ok(())
588 }
589 }
590}
591
592pub struct Field {
597 name: String,
599 kind: FieldKind,
601}
602
603#[derive(Debug)]
605pub enum VisitError {
606 Io(std::io::Error),
608 UnknownFieldType(u8),
612 FieldDoesNotExist(String),
615 FieldAlreadyExists(String),
618 RegionAlreadyExists(String),
621 InvalidCurrentNode,
622 FieldTypeDoesNotMatch,
625 RegionDoesNotExist(String),
628 NoActiveNode,
630 NotSupportedFormat,
632 InvalidName,
634 TypeMismatch,
639 RefCellAlreadyMutableBorrowed,
641 User(String),
643 UnexpectedRcNullIndex,
646 PoisonedMutex,
648 FileLoadError(FileLoadError),
650}
651
652impl Error for VisitError {}
653
654impl Display for VisitError {
655 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
656 match self {
657 Self::Io(io) => write!(f, "io error: {io}"),
658 Self::UnknownFieldType(type_index) => write!(f, "unknown field type {type_index}"),
659 Self::FieldDoesNotExist(name) => write!(f, "field does not exists {name}"),
660 Self::FieldAlreadyExists(name) => write!(f, "field already exists {name}"),
661 Self::RegionAlreadyExists(name) => write!(f, "region already exists {name}"),
662 Self::InvalidCurrentNode => write!(f, "invalid current node"),
663 Self::FieldTypeDoesNotMatch => write!(f, "field type does not match"),
664 Self::RegionDoesNotExist(name) => write!(f, "region does not exists {name}"),
665 Self::NoActiveNode => write!(f, "no active node"),
666 Self::NotSupportedFormat => write!(f, "not supported format"),
667 Self::InvalidName => write!(f, "invalid name"),
668 Self::TypeMismatch => write!(f, "type mismatch"),
669 Self::RefCellAlreadyMutableBorrowed => write!(f, "ref cell already mutable borrowed"),
670 Self::User(msg) => write!(f, "user defined error: {msg}"),
671 Self::UnexpectedRcNullIndex => write!(f, "unexpected rc null index"),
672 Self::PoisonedMutex => write!(f, "attempt to lock poisoned mutex"),
673 Self::FileLoadError(e) => write!(f, "file load error: {e:?}"),
674 }
675 }
676}
677
678impl<T> From<std::sync::PoisonError<std::sync::MutexGuard<'_, T>>> for VisitError {
679 fn from(_: std::sync::PoisonError<std::sync::MutexGuard<'_, T>>) -> Self {
680 Self::PoisonedMutex
681 }
682}
683
684impl<T> From<std::sync::PoisonError<&mut T>> for VisitError {
685 fn from(_: std::sync::PoisonError<&mut T>) -> Self {
686 Self::PoisonedMutex
687 }
688}
689
690impl<T> From<std::sync::PoisonError<std::sync::RwLockWriteGuard<'_, T>>> for VisitError {
691 fn from(_: std::sync::PoisonError<std::sync::RwLockWriteGuard<'_, T>>) -> Self {
692 Self::PoisonedMutex
693 }
694}
695
696impl From<std::io::Error> for VisitError {
697 fn from(io_err: std::io::Error) -> Self {
698 Self::Io(io_err)
699 }
700}
701
702impl From<FromUtf8Error> for VisitError {
703 fn from(_: FromUtf8Error) -> Self {
704 Self::InvalidName
705 }
706}
707
708impl From<String> for VisitError {
709 fn from(s: String) -> Self {
710 Self::User(s)
711 }
712}
713
714impl From<FileLoadError> for VisitError {
715 fn from(e: FileLoadError) -> Self {
716 Self::FileLoadError(e)
717 }
718}
719
720pub type VisitResult = Result<(), VisitError>;
723
724trait VisitableElementaryField {
725 fn write(&self, file: &mut dyn Write) -> VisitResult;
726 fn read(&mut self, file: &mut dyn Read) -> VisitResult;
727}
728
729macro_rules! impl_visitable_elementary_field {
730 ($ty:ty, $write:ident, $read:ident $(, $endian:ident)*) => {
731 impl VisitableElementaryField for $ty {
732 fn write(&self, file: &mut dyn Write) -> VisitResult {
733 file.$write::<$($endian)*>(*self)?;
734 Ok(())
735 }
736
737 fn read(&mut self, file: &mut dyn Read) -> VisitResult {
738 *self = file.$read::<$($endian)*>()?;
739 Ok(())
740 }
741 }
742 };
743}
744impl_visitable_elementary_field!(f64, write_f64, read_f64, LittleEndian);
745impl_visitable_elementary_field!(f32, write_f32, read_f32, LittleEndian);
746impl_visitable_elementary_field!(u8, write_u8, read_u8);
747impl_visitable_elementary_field!(i8, write_i8, read_i8);
748impl_visitable_elementary_field!(u16, write_u16, read_u16, LittleEndian);
749impl_visitable_elementary_field!(i16, write_i16, read_i16, LittleEndian);
750impl_visitable_elementary_field!(u32, write_u32, read_u32, LittleEndian);
751impl_visitable_elementary_field!(i32, write_i32, read_i32, LittleEndian);
752impl_visitable_elementary_field!(u64, write_u64, read_u64, LittleEndian);
753impl_visitable_elementary_field!(i64, write_i64, read_i64, LittleEndian);
754
755impl Field {
756 pub fn new(name: &str, kind: FieldKind) -> Self {
757 Self {
758 name: name.to_owned(),
759 kind,
760 }
761 }
762
763 fn save(field: &Field, file: &mut dyn Write) -> VisitResult {
764 fn write_vec_n<T, const N: usize>(
765 file: &mut dyn Write,
766 type_id: u8,
767 vec: &SVector<T, N>,
768 ) -> VisitResult
769 where
770 T: VisitableElementaryField,
771 {
772 file.write_u8(type_id)?;
773 for v in vec.iter() {
774 v.write(file)?;
775 }
776 Ok(())
777 }
778
779 let name = field.name.as_bytes();
780 file.write_u32::<LittleEndian>(name.len() as u32)?;
781 file.write_all(name)?;
782 match &field.kind {
783 FieldKind::U8(data) => {
784 file.write_u8(1)?;
785 file.write_u8(*data)?;
786 }
787 FieldKind::I8(data) => {
788 file.write_i8(2)?;
789 file.write_i8(*data)?;
790 }
791 FieldKind::U16(data) => {
792 file.write_u8(3)?;
793 file.write_u16::<LittleEndian>(*data)?;
794 }
795 FieldKind::I16(data) => {
796 file.write_u8(4)?;
797 file.write_i16::<LittleEndian>(*data)?;
798 }
799 FieldKind::U32(data) => {
800 file.write_u8(5)?;
801 file.write_u32::<LittleEndian>(*data)?;
802 }
803 FieldKind::I32(data) => {
804 file.write_u8(6)?;
805 file.write_i32::<LittleEndian>(*data)?;
806 }
807 FieldKind::U64(data) => {
808 file.write_u8(7)?;
809 file.write_u64::<LittleEndian>(*data)?;
810 }
811 FieldKind::I64(data) => {
812 file.write_u8(8)?;
813 file.write_i64::<LittleEndian>(*data)?;
814 }
815 FieldKind::F32(data) => {
816 file.write_u8(9)?;
817 file.write_f32::<LittleEndian>(*data)?;
818 }
819 FieldKind::F64(data) => {
820 file.write_u8(10)?;
821 file.write_f64::<LittleEndian>(*data)?;
822 }
823 FieldKind::Vector3F32(data) => {
824 write_vec_n(file, 11, data)?;
825 }
826 FieldKind::UnitQuaternion(data) => {
827 file.write_u8(12)?;
828 file.write_f32::<LittleEndian>(data.i)?;
829 file.write_f32::<LittleEndian>(data.j)?;
830 file.write_f32::<LittleEndian>(data.k)?;
831 file.write_f32::<LittleEndian>(data.w)?;
832 }
833 FieldKind::Matrix4(data) => {
834 file.write_u8(13)?;
835 for f in data.iter() {
836 file.write_f32::<LittleEndian>(*f)?;
837 }
838 }
839 FieldKind::BinaryBlob(data) => {
840 file.write_u8(14)?;
841 file.write_u32::<LittleEndian>(data.len() as u32)?;
842 file.write_all(data.as_slice())?;
843 }
844 FieldKind::Bool(data) => {
845 file.write_u8(15)?;
846 file.write_u8(u8::from(*data))?;
847 }
848 FieldKind::Matrix3(data) => {
849 file.write_u8(16)?;
850 for f in data.iter() {
851 file.write_f32::<LittleEndian>(*f)?;
852 }
853 }
854 FieldKind::Vector2F32(data) => {
855 write_vec_n(file, 17, data)?;
856 }
857 FieldKind::Vector4F32(data) => {
858 write_vec_n(file, 18, data)?;
859 }
860 FieldKind::Uuid(uuid) => {
861 file.write_u8(19)?;
862 file.write_all(uuid.as_bytes())?;
863 }
864 FieldKind::UnitComplex(c) => {
865 file.write_u8(20)?;
866 file.write_f32::<LittleEndian>(c.re)?;
867 file.write_f32::<LittleEndian>(c.im)?;
868 }
869 FieldKind::PodArray {
870 type_id,
871 element_size,
872 bytes,
873 } => {
874 file.write_u8(21)?;
875 file.write_u8(*type_id)?;
876 file.write_u32::<LittleEndian>(*element_size)?;
877 file.write_u64::<LittleEndian>(bytes.len() as u64)?;
878 file.write_all(bytes)?;
879 }
880 FieldKind::Matrix2(data) => {
881 file.write_u8(22)?;
882 for f in data.iter() {
883 file.write_f32::<LittleEndian>(*f)?;
884 }
885 }
886 FieldKind::Vector2F64(data) => {
887 write_vec_n(file, 23, data)?;
888 }
889 FieldKind::Vector3F64(data) => {
890 write_vec_n(file, 24, data)?;
891 }
892 FieldKind::Vector4F64(data) => {
893 write_vec_n(file, 25, data)?;
894 }
895
896 FieldKind::Vector2I8(data) => {
897 write_vec_n(file, 26, data)?;
898 }
899 FieldKind::Vector3I8(data) => {
900 write_vec_n(file, 27, data)?;
901 }
902 FieldKind::Vector4I8(data) => {
903 write_vec_n(file, 28, data)?;
904 }
905
906 FieldKind::Vector2U8(data) => {
907 write_vec_n(file, 29, data)?;
908 }
909 FieldKind::Vector3U8(data) => {
910 write_vec_n(file, 30, data)?;
911 }
912 FieldKind::Vector4U8(data) => {
913 write_vec_n(file, 31, data)?;
914 }
915
916 FieldKind::Vector2I16(data) => {
917 write_vec_n(file, 32, data)?;
918 }
919 FieldKind::Vector3I16(data) => {
920 write_vec_n(file, 33, data)?;
921 }
922 FieldKind::Vector4I16(data) => {
923 write_vec_n(file, 34, data)?;
924 }
925
926 FieldKind::Vector2U16(data) => {
927 write_vec_n(file, 35, data)?;
928 }
929 FieldKind::Vector3U16(data) => {
930 write_vec_n(file, 36, data)?;
931 }
932 FieldKind::Vector4U16(data) => {
933 write_vec_n(file, 37, data)?;
934 }
935
936 FieldKind::Vector2I32(data) => {
937 write_vec_n(file, 38, data)?;
938 }
939 FieldKind::Vector3I32(data) => {
940 write_vec_n(file, 39, data)?;
941 }
942 FieldKind::Vector4I32(data) => {
943 write_vec_n(file, 40, data)?;
944 }
945
946 FieldKind::Vector2U32(data) => {
947 write_vec_n(file, 41, data)?;
948 }
949 FieldKind::Vector3U32(data) => {
950 write_vec_n(file, 42, data)?;
951 }
952 FieldKind::Vector4U32(data) => {
953 write_vec_n(file, 43, data)?;
954 }
955
956 FieldKind::Vector2I64(data) => {
957 write_vec_n(file, 44, data)?;
958 }
959 FieldKind::Vector3I64(data) => {
960 write_vec_n(file, 45, data)?;
961 }
962 FieldKind::Vector4I64(data) => {
963 write_vec_n(file, 46, data)?;
964 }
965
966 FieldKind::Vector2U64(data) => {
967 write_vec_n(file, 47, data)?;
968 }
969 FieldKind::Vector3U64(data) => {
970 write_vec_n(file, 48, data)?;
971 }
972 FieldKind::Vector4U64(data) => {
973 write_vec_n(file, 49, data)?;
974 }
975 }
976 Ok(())
977 }
978
979 fn load(file: &mut dyn Read) -> Result<Field, VisitError> {
980 fn read_vec_n<T, S, const N: usize>(
981 file: &mut dyn Read,
982 ) -> Result<Matrix<T, Const<N>, U1, S>, VisitError>
983 where
984 T: VisitableElementaryField + Scalar + Default,
985 S: RawStorage<T, Const<N>> + RawStorageMut<T, Const<N>> + Default,
986 {
987 let mut vec = Matrix::<T, Const<N>, U1, S>::default();
988 for v in vec.iter_mut() {
989 v.read(file)?;
990 }
991 Ok(vec)
992 }
993
994 let name_len = file.read_u32::<LittleEndian>()? as usize;
995 let mut raw_name = vec![Default::default(); name_len];
996 file.read_exact(raw_name.as_mut_slice())?;
997 let id = file.read_u8()?;
998 Ok(Field::new(
999 String::from_utf8(raw_name)?.as_str(),
1000 match id {
1001 1 => FieldKind::U8(file.read_u8()?),
1002 2 => FieldKind::I8(file.read_i8()?),
1003 3 => FieldKind::U16(file.read_u16::<LittleEndian>()?),
1004 4 => FieldKind::I16(file.read_i16::<LittleEndian>()?),
1005 5 => FieldKind::U32(file.read_u32::<LittleEndian>()?),
1006 6 => FieldKind::I32(file.read_i32::<LittleEndian>()?),
1007 7 => FieldKind::U64(file.read_u64::<LittleEndian>()?),
1008 8 => FieldKind::I64(file.read_i64::<LittleEndian>()?),
1009 9 => FieldKind::F32(file.read_f32::<LittleEndian>()?),
1010 10 => FieldKind::F64(file.read_f64::<LittleEndian>()?),
1011 11 => FieldKind::Vector3F32({
1012 let x = file.read_f32::<LittleEndian>()?;
1013 let y = file.read_f32::<LittleEndian>()?;
1014 let z = file.read_f32::<LittleEndian>()?;
1015 Vector3::new(x, y, z)
1016 }),
1017 12 => FieldKind::UnitQuaternion({
1018 let x = file.read_f32::<LittleEndian>()?;
1019 let y = file.read_f32::<LittleEndian>()?;
1020 let z = file.read_f32::<LittleEndian>()?;
1021 let w = file.read_f32::<LittleEndian>()?;
1022 UnitQuaternion::new_normalize(Quaternion::new(w, x, y, z))
1023 }),
1024 13 => FieldKind::Matrix4({
1025 let mut f = [0.0f32; 16];
1026 for n in &mut f {
1027 *n = file.read_f32::<LittleEndian>()?;
1028 }
1029 Matrix4::from_row_slice(&f)
1030 }),
1031 14 => FieldKind::BinaryBlob({
1032 let len = file.read_u32::<LittleEndian>()? as usize;
1033 let mut vec = vec![Default::default(); len];
1034 file.read_exact(vec.as_mut_slice())?;
1035 vec
1036 }),
1037 15 => FieldKind::Bool(file.read_u8()? != 0),
1038 16 => FieldKind::Matrix3({
1039 let mut f = [0.0f32; 9];
1040 for n in &mut f {
1041 *n = file.read_f32::<LittleEndian>()?;
1042 }
1043 Matrix3::from_row_slice(&f)
1044 }),
1045 17 => FieldKind::Vector2F32({
1046 let x = file.read_f32::<LittleEndian>()?;
1047 let y = file.read_f32::<LittleEndian>()?;
1048 Vector2::new(x, y)
1049 }),
1050 18 => FieldKind::Vector4F32({
1051 let x = file.read_f32::<LittleEndian>()?;
1052 let y = file.read_f32::<LittleEndian>()?;
1053 let z = file.read_f32::<LittleEndian>()?;
1054 let w = file.read_f32::<LittleEndian>()?;
1055 Vector4::new(x, y, z, w)
1056 }),
1057 19 => FieldKind::Uuid({
1058 let mut bytes = uuid::Bytes::default();
1059 file.read_exact(&mut bytes)?;
1060 Uuid::from_bytes(bytes)
1061 }),
1062 20 => FieldKind::UnitComplex({
1063 let re = file.read_f32::<LittleEndian>()?;
1064 let im = file.read_f32::<LittleEndian>()?;
1065 UnitComplex::from_complex(Complex::new(re, im))
1066 }),
1067 21 => {
1068 let type_id = file.read_u8()?;
1069 let element_size = file.read_u32::<LittleEndian>()?;
1070 let data_size = file.read_u64::<LittleEndian>()?;
1071 let mut bytes = vec![0; data_size as usize];
1072 file.read_exact(&mut bytes)?;
1073 FieldKind::PodArray {
1074 type_id,
1075 element_size,
1076 bytes,
1077 }
1078 }
1079 22 => FieldKind::Matrix2({
1080 let mut f = [0.0f32; 3];
1081 for n in &mut f {
1082 *n = file.read_f32::<LittleEndian>()?;
1083 }
1084 Matrix2::from_row_slice(&f)
1085 }),
1086 23 => FieldKind::Vector2F64(read_vec_n(file)?),
1087 24 => FieldKind::Vector3F64(read_vec_n(file)?),
1088 25 => FieldKind::Vector4F64(read_vec_n(file)?),
1089
1090 26 => FieldKind::Vector2I8(read_vec_n(file)?),
1091 27 => FieldKind::Vector3I8(read_vec_n(file)?),
1092 28 => FieldKind::Vector4I8(read_vec_n(file)?),
1093
1094 29 => FieldKind::Vector2U8(read_vec_n(file)?),
1095 30 => FieldKind::Vector3U8(read_vec_n(file)?),
1096 31 => FieldKind::Vector4U8(read_vec_n(file)?),
1097
1098 32 => FieldKind::Vector2I16(read_vec_n(file)?),
1099 33 => FieldKind::Vector3I16(read_vec_n(file)?),
1100 34 => FieldKind::Vector4I16(read_vec_n(file)?),
1101
1102 35 => FieldKind::Vector2U16(read_vec_n(file)?),
1103 36 => FieldKind::Vector3U16(read_vec_n(file)?),
1104 37 => FieldKind::Vector4U16(read_vec_n(file)?),
1105
1106 38 => FieldKind::Vector2I32(read_vec_n(file)?),
1107 39 => FieldKind::Vector3I32(read_vec_n(file)?),
1108 40 => FieldKind::Vector4I32(read_vec_n(file)?),
1109
1110 41 => FieldKind::Vector2U32(read_vec_n(file)?),
1111 42 => FieldKind::Vector3U32(read_vec_n(file)?),
1112 43 => FieldKind::Vector4U32(read_vec_n(file)?),
1113
1114 44 => FieldKind::Vector2I64(read_vec_n(file)?),
1115 45 => FieldKind::Vector3I64(read_vec_n(file)?),
1116 46 => FieldKind::Vector4I64(read_vec_n(file)?),
1117
1118 47 => FieldKind::Vector2U64(read_vec_n(file)?),
1119 48 => FieldKind::Vector3U64(read_vec_n(file)?),
1120 49 => FieldKind::Vector4U64(read_vec_n(file)?),
1121
1122 _ => return Err(VisitError::UnknownFieldType(id)),
1123 },
1124 ))
1125 }
1126
1127 fn as_string(&self) -> String {
1128 format!("{}{}", self.name, self.kind.as_string())
1129 }
1130}
1131
1132pub struct VisitorNode {
1136 name: String,
1137 fields: Vec<Field>,
1138 parent: Handle<VisitorNode>,
1139 children: Vec<Handle<VisitorNode>>,
1140}
1141
1142impl VisitorNode {
1143 fn new(name: &str, parent: Handle<VisitorNode>) -> Self {
1144 Self {
1145 name: name.to_owned(),
1146 fields: Vec::new(),
1147 parent,
1148 children: Vec::new(),
1149 }
1150 }
1151}
1152
1153impl Default for VisitorNode {
1154 fn default() -> Self {
1155 Self {
1156 name: String::new(),
1157 fields: Vec::new(),
1158 parent: Handle::NONE,
1159 children: Vec::new(),
1160 }
1161 }
1162}
1163
1164#[must_use = "the guard must be used"]
1167pub struct RegionGuard<'a>(&'a mut Visitor);
1168
1169impl Deref for RegionGuard<'_> {
1170 type Target = Visitor;
1171
1172 fn deref(&self) -> &Self::Target {
1173 self.0
1174 }
1175}
1176
1177impl DerefMut for RegionGuard<'_> {
1178 fn deref_mut(&mut self) -> &mut Self::Target {
1179 self.0
1180 }
1181}
1182
1183impl Drop for RegionGuard<'_> {
1184 fn drop(&mut self) {
1185 self.0.leave_region().unwrap();
1188 }
1189}
1190
1191#[derive(Default)]
1194pub struct Blackboard {
1195 items: FxHashMap<TypeId, Arc<dyn Any>>,
1196}
1197
1198impl Blackboard {
1199 pub fn new() -> Self {
1200 Self {
1201 items: Default::default(),
1202 }
1203 }
1204
1205 pub fn register<T: Any>(&mut self, value: Arc<T>) {
1206 self.items.insert(TypeId::of::<T>(), value);
1207 }
1208
1209 pub fn get<T: Any>(&self) -> Option<&T> {
1210 self.items
1211 .get(&TypeId::of::<T>())
1212 .and_then(|v| (**v).downcast_ref::<T>())
1213 }
1214
1215 pub fn inner(&self) -> &FxHashMap<TypeId, Arc<dyn Any>> {
1216 &self.items
1217 }
1218
1219 pub fn inner_mut(&mut self) -> &mut FxHashMap<TypeId, Arc<dyn Any>> {
1220 &mut self.items
1221 }
1222}
1223
1224bitflags! {
1225 pub struct VisitorFlags: u32 {
1227 const NONE = 0;
1229 const SERIALIZE_EVERYTHING = 1 << 1;
1234 }
1235}
1236
1237pub struct Visitor {
1251 nodes: Pool<VisitorNode>,
1252 rc_map: FxHashMap<u64, Rc<dyn Any>>,
1253 arc_map: FxHashMap<u64, Arc<dyn Any + Send + Sync>>,
1254 reading: bool,
1255 current_node: Handle<VisitorNode>,
1256 root: Handle<VisitorNode>,
1257 pub blackboard: Blackboard,
1259 pub flags: VisitorFlags,
1262}
1263
1264pub trait Visit {
1266 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult;
1305}
1306
1307impl Default for Visitor {
1308 fn default() -> Self {
1309 Self::new()
1310 }
1311}
1312
1313impl Visitor {
1314 pub const MAGIC: &'static str = "RG3D";
1322
1323 pub fn new() -> Self {
1326 let mut nodes = Pool::new();
1327 let root = nodes.spawn(VisitorNode::new("__ROOT__", Handle::NONE));
1328 Self {
1329 nodes,
1330 rc_map: FxHashMap::default(),
1331 arc_map: FxHashMap::default(),
1332 reading: false,
1333 current_node: root,
1334 root,
1335 blackboard: Blackboard::new(),
1336 flags: VisitorFlags::NONE,
1337 }
1338 }
1339
1340 fn find_field(&mut self, name: &str) -> Option<&mut Field> {
1341 self.nodes
1342 .borrow_mut(self.current_node)
1343 .fields
1344 .iter_mut()
1345 .find(|field| field.name == name)
1346 }
1347
1348 pub fn is_reading(&self) -> bool {
1356 self.reading
1357 }
1358
1359 fn current_node(&mut self) -> &mut VisitorNode {
1360 self.nodes.borrow_mut(self.current_node)
1361 }
1362
1363 pub fn enter_region(&mut self, name: &str) -> Result<RegionGuard, VisitError> {
1371 let node = self.nodes.borrow(self.current_node);
1372 if self.reading {
1373 let mut region = Handle::NONE;
1374 for child_handle in node.children.iter() {
1375 let child = self.nodes.borrow(*child_handle);
1376 if child.name == name {
1377 region = *child_handle;
1378 break;
1379 }
1380 }
1381 if region.is_some() {
1382 self.current_node = region;
1383 Ok(RegionGuard(self))
1384 } else {
1385 Err(VisitError::RegionDoesNotExist(name.to_owned()))
1386 }
1387 } else {
1388 for child_handle in node.children.iter() {
1390 let child = self.nodes.borrow(*child_handle);
1391 if child.name == name {
1392 return Err(VisitError::RegionAlreadyExists(name.to_owned()));
1393 }
1394 }
1395
1396 let node_handle = self.nodes.spawn(VisitorNode::new(name, self.current_node));
1397 self.nodes
1398 .borrow_mut(self.current_node)
1399 .children
1400 .push(node_handle);
1401 self.current_node = node_handle;
1402
1403 Ok(RegionGuard(self))
1404 }
1405 }
1406
1407 pub fn current_region(&self) -> Option<&str> {
1411 self.nodes
1412 .try_borrow(self.current_node)
1413 .map(|n| n.name.as_str())
1414 }
1415
1416 fn leave_region(&mut self) -> VisitResult {
1417 self.current_node = self.nodes.borrow(self.current_node).parent;
1418 if self.current_node.is_none() {
1419 Err(VisitError::NoActiveNode)
1420 } else {
1421 Ok(())
1422 }
1423 }
1424
1425 fn print_node(
1426 &self,
1427 node_handle: Handle<VisitorNode>,
1428 nesting: usize,
1429 out_string: &mut String,
1430 ) {
1431 let offset = (0..nesting).map(|_| "\t").collect::<String>();
1432 let node = self.nodes.borrow(node_handle);
1433 *out_string += format!(
1434 "{}{}[Fields={}, Children={}]: ",
1435 offset,
1436 node.name,
1437 node.fields.len(),
1438 node.children.len()
1439 )
1440 .as_str();
1441 for field in node.fields.iter() {
1442 *out_string += field.as_string().as_str();
1443 }
1444
1445 *out_string += "\n";
1446
1447 for child_handle in node.children.iter() {
1448 self.print_node(*child_handle, nesting + 1, out_string);
1449 }
1450 }
1451
1452 pub fn save_text(&self) -> String {
1456 let mut out_string = String::new();
1457 self.print_node(self.root, 0, &mut out_string);
1458 out_string
1459 }
1460
1461 pub fn save_binary_to_memory<W: Write>(&self, mut writer: W) -> VisitResult {
1464 writer.write_all(Self::MAGIC.as_bytes())?;
1465 let mut stack = vec![self.root];
1466 while let Some(node_handle) = stack.pop() {
1467 let node = self.nodes.borrow(node_handle);
1468 let name = node.name.as_bytes();
1469 writer.write_u32::<LittleEndian>(name.len() as u32)?;
1470 writer.write_all(name)?;
1471
1472 writer.write_u32::<LittleEndian>(node.fields.len() as u32)?;
1473 for field in node.fields.iter() {
1474 Field::save(field, &mut writer)?
1475 }
1476
1477 writer.write_u32::<LittleEndian>(node.children.len() as u32)?;
1478 stack.extend_from_slice(&node.children);
1479 }
1480 Ok(())
1481 }
1482
1483 pub fn save_binary_to_vec(&self) -> Result<Vec<u8>, VisitError> {
1487 let mut writer = Cursor::new(Vec::new());
1488 self.save_binary_to_memory(&mut writer)?;
1489 Ok(writer.into_inner())
1490 }
1491
1492 pub fn save_binary<P: AsRef<Path>>(&self, path: P) -> VisitResult {
1497 let writer = BufWriter::new(File::create(path)?);
1498 self.save_binary_to_memory(writer)
1499 }
1500
1501 fn load_node_binary(&mut self, file: &mut dyn Read) -> Result<Handle<VisitorNode>, VisitError> {
1502 let name_len = file.read_u32::<LittleEndian>()? as usize;
1503 let mut raw_name = vec![Default::default(); name_len];
1504 file.read_exact(raw_name.as_mut_slice())?;
1505
1506 let mut node = VisitorNode {
1507 name: String::from_utf8(raw_name)?,
1508 ..VisitorNode::default()
1509 };
1510
1511 let field_count = file.read_u32::<LittleEndian>()? as usize;
1512 for _ in 0..field_count {
1513 let field = Field::load(file)?;
1514 node.fields.push(field);
1515 }
1516
1517 let child_count = file.read_u32::<LittleEndian>()? as usize;
1518 let mut children = Vec::with_capacity(child_count);
1519 for _ in 0..child_count {
1520 children.push(self.load_node_binary(file)?);
1521 }
1522
1523 node.children.clone_from(&children);
1524
1525 let handle = self.nodes.spawn(node);
1526 for child_handle in children.iter() {
1527 let child = self.nodes.borrow_mut(*child_handle);
1528 child.parent = handle;
1529 }
1530
1531 Ok(handle)
1532 }
1533
1534 pub async fn load_binary<P: AsRef<Path>>(path: P) -> Result<Self, VisitError> {
1538 Self::load_from_memory(&io::load_file(path).await?)
1539 }
1540
1541 pub fn load_from_memory(data: &[u8]) -> Result<Self, VisitError> {
1546 let mut reader = Cursor::new(data);
1547 let mut magic: [u8; 4] = Default::default();
1548 reader.read_exact(&mut magic)?;
1549 if !magic.eq(Self::MAGIC.as_bytes()) {
1550 return Err(VisitError::NotSupportedFormat);
1551 }
1552 let mut visitor = Self {
1553 nodes: Pool::new(),
1554 rc_map: Default::default(),
1555 arc_map: Default::default(),
1556 reading: true,
1557 current_node: Handle::NONE,
1558 root: Handle::NONE,
1559 blackboard: Blackboard::new(),
1560 flags: VisitorFlags::NONE,
1561 };
1562 visitor.root = visitor.load_node_binary(&mut reader)?;
1563 visitor.current_node = visitor.root;
1564 Ok(visitor)
1565 }
1566}
1567
1568impl<T> Visit for RefCell<T>
1569where
1570 T: Visit + 'static,
1571{
1572 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1573 if let Ok(mut data) = self.try_borrow_mut() {
1574 data.visit(name, visitor)
1575 } else {
1576 Err(VisitError::RefCellAlreadyMutableBorrowed)
1577 }
1578 }
1579}
1580
1581impl<T> Visit for Vec<T>
1582where
1583 T: Default + Visit + 'static,
1584{
1585 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1586 let mut region = visitor.enter_region(name)?;
1587
1588 let mut len = self.len() as u32;
1589 len.visit("Length", &mut region)?;
1590
1591 if region.reading {
1592 self.clear();
1593 for index in 0..len {
1594 let region_name = format!("Item{index}");
1595 let mut region = region.enter_region(region_name.as_str())?;
1596 let mut object = T::default();
1597 object.visit("ItemData", &mut region)?;
1598 self.push(object);
1599 }
1600 } else {
1601 for (index, item) in self.iter_mut().enumerate() {
1602 let region_name = format!("Item{index}");
1603 let mut region = region.enter_region(region_name.as_str())?;
1604 item.visit("ItemData", &mut region)?;
1605 }
1606 }
1607
1608 Ok(())
1609 }
1610}
1611
1612impl<T> Visit for Option<T>
1613where
1614 T: Default + Visit + 'static,
1615{
1616 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1617 let mut region = visitor.enter_region(name)?;
1618
1619 let mut is_some = u8::from(self.is_some());
1620 is_some.visit("IsSome", &mut region)?;
1621
1622 if is_some != 0 {
1623 if region.reading {
1624 let mut value = T::default();
1625 value.visit("Data", &mut region)?;
1626 *self = Some(value);
1627 } else {
1628 self.as_mut().unwrap().visit("Data", &mut region)?;
1629 }
1630 }
1631
1632 Ok(())
1633 }
1634}
1635
1636impl Visit for String {
1637 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1638 let mut region = visitor.enter_region(name)?;
1639
1640 let mut len = self.len() as u32;
1641 len.visit("Length", &mut region)?;
1642
1643 let mut data = if region.reading {
1644 Vec::new()
1645 } else {
1646 Vec::from(self.as_bytes())
1647 };
1648
1649 let mut proxy = BinaryBlob { vec: &mut data };
1650 proxy.visit("Data", &mut region)?;
1651
1652 if region.reading {
1653 *self = String::from_utf8(data)?;
1654 }
1655 Ok(())
1656 }
1657}
1658
1659impl Visit for PathBuf {
1660 #[allow(clippy::needless_borrows_for_generic_args)] fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1662 let mut region = visitor.enter_region(name)?;
1663
1664 let portable_path = replace_slashes(&self);
1667
1668 let bytes = if let Some(path_str) = portable_path.as_os_str().to_str() {
1669 path_str.as_bytes()
1670 } else {
1671 return Err(VisitError::InvalidName);
1672 };
1673
1674 let mut len = bytes.len() as u32;
1675 len.visit("Length", &mut region)?;
1676
1677 let mut data = if region.reading {
1678 Vec::new()
1679 } else {
1680 Vec::from(bytes)
1681 };
1682
1683 let mut proxy = BinaryBlob { vec: &mut data };
1684 proxy.visit("Data", &mut region)?;
1685
1686 if region.reading {
1687 *self = PathBuf::from(String::from_utf8(data)?);
1688 }
1689
1690 Ok(())
1691 }
1692}
1693
1694impl<T> Visit for Cell<T>
1695where
1696 T: Copy + Clone + Visit + 'static,
1697{
1698 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1699 let mut value = self.get();
1700 value.visit(name, visitor)?;
1701 if visitor.is_reading() {
1702 self.set(value);
1703 }
1704 Ok(())
1705 }
1706}
1707
1708impl<T> Visit for Rc<T>
1709where
1710 T: Visit + 'static,
1711{
1712 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1713 let mut region = visitor.enter_region(name)?;
1714
1715 if region.reading {
1716 let mut raw = 0u64;
1717 raw.visit("Id", &mut region)?;
1718 if raw == 0 {
1719 return Err(VisitError::UnexpectedRcNullIndex);
1720 }
1721 if let Some(ptr) = region.rc_map.get(&raw) {
1722 if let Ok(res) = Rc::downcast::<T>(ptr.clone()) {
1723 *self = res;
1724 } else {
1725 return Err(VisitError::TypeMismatch);
1726 }
1727 } else {
1728 region.rc_map.insert(raw, self.clone());
1730
1731 let raw = rc_to_raw(self);
1732 unsafe { &mut *raw }.visit("RcData", &mut region)?;
1733 }
1734 } else {
1735 let raw = rc_to_raw(self);
1737
1738 let mut index = raw as u64;
1740 index.visit("Id", &mut region)?;
1741
1742 if let Entry::Vacant(entry) = region.rc_map.entry(index) {
1743 entry.insert(self.clone());
1744 unsafe { &mut *raw }.visit("RcData", &mut region)?;
1745 }
1746 }
1747
1748 Ok(())
1749 }
1750}
1751
1752impl<T> Visit for Mutex<T>
1753where
1754 T: Visit + Send,
1755{
1756 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1757 self.get_mut()?.visit(name, visitor)
1758 }
1759}
1760
1761impl<T> Visit for parking_lot::Mutex<T>
1762where
1763 T: Visit + Send,
1764{
1765 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1766 self.get_mut().visit(name, visitor)
1767 }
1768}
1769
1770impl<T> Visit for Box<T>
1771where
1772 T: Visit,
1773{
1774 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1775 self.deref_mut().visit(name, visitor)
1776 }
1777}
1778
1779impl<T> Visit for RwLock<T>
1780where
1781 T: Visit + Send,
1782{
1783 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1784 self.write()?.visit(name, visitor)
1785 }
1786}
1787
1788fn arc_to_raw<T>(arc: &Arc<T>) -> *mut T {
1789 &**arc as *const T as *mut T
1790}
1791
1792fn rc_to_raw<T>(rc: &Rc<T>) -> *mut T {
1793 &**rc as *const T as *mut T
1794}
1795
1796impl<T> Visit for Arc<T>
1797where
1798 T: Visit + Send + Sync + 'static,
1799{
1800 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1801 let mut region = visitor.enter_region(name)?;
1802
1803 if region.reading {
1804 let mut raw = 0u64;
1805 raw.visit("Id", &mut region)?;
1806 if raw == 0 {
1807 return Err(VisitError::UnexpectedRcNullIndex);
1808 }
1809 if let Some(ptr) = &mut region.arc_map.get(&raw) {
1810 if let Ok(res) = Arc::downcast::<T>(ptr.clone()) {
1811 *self = res;
1812 } else {
1813 return Err(VisitError::TypeMismatch);
1814 }
1815 } else {
1816 region.arc_map.insert(raw, self.clone());
1818
1819 let raw = arc_to_raw(self);
1820 unsafe { &mut *raw }.visit("ArcData", &mut region)?;
1821 }
1822 } else {
1823 let raw = arc_to_raw(self);
1825
1826 let mut index = raw as u64;
1828 index.visit("Id", &mut region)?;
1829
1830 if let Entry::Vacant(entry) = region.arc_map.entry(index) {
1831 entry.insert(self.clone());
1832 unsafe { &mut *raw }.visit("ArcData", &mut region)?;
1833 }
1834 }
1835
1836 Ok(())
1837 }
1838}
1839
1840impl<T> Visit for std::rc::Weak<T>
1841where
1842 T: Default + Visit + 'static,
1843{
1844 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1845 let mut region = visitor.enter_region(name)?;
1846
1847 if region.reading {
1848 let mut raw = 0u64;
1849 raw.visit("Id", &mut region)?;
1850
1851 if raw != 0 {
1852 if let Some(ptr) = &mut region.rc_map.get(&raw) {
1853 if let Ok(res) = Rc::downcast::<T>(ptr.clone()) {
1854 *self = Rc::downgrade(&res);
1855 } else {
1856 return Err(VisitError::TypeMismatch);
1857 }
1858 } else {
1859 let rc = Rc::new(T::default());
1861 region.rc_map.insert(raw, rc.clone());
1862
1863 let raw = rc_to_raw(&rc);
1864 unsafe { &mut *raw }.visit("RcData", &mut region)?;
1865
1866 *self = Rc::downgrade(&rc);
1867 }
1868 }
1869 } else if let Some(rc) = std::rc::Weak::upgrade(self) {
1870 let raw = rc_to_raw(&rc);
1872
1873 let mut index = raw as u64;
1875 index.visit("Id", &mut region)?;
1876
1877 if let Entry::Vacant(entry) = region.rc_map.entry(index) {
1878 entry.insert(rc);
1879 unsafe { &mut *raw }.visit("RcData", &mut region)?;
1880 }
1881 } else {
1882 let mut index = 0u64;
1883 index.visit("Id", &mut region)?;
1884 }
1885
1886 Ok(())
1887 }
1888}
1889
1890impl<T> Visit for std::sync::Weak<T>
1891where
1892 T: Default + Visit + Send + Sync + 'static,
1893{
1894 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1895 let mut region = visitor.enter_region(name)?;
1896
1897 if region.reading {
1898 let mut raw = 0u64;
1899 raw.visit("Id", &mut region)?;
1900
1901 if raw != 0 {
1902 if let Some(ptr) = region.arc_map.get(&raw) {
1903 if let Ok(res) = Arc::downcast::<T>(ptr.clone()) {
1904 *self = Arc::downgrade(&res);
1905 } else {
1906 return Err(VisitError::TypeMismatch);
1907 }
1908 } else {
1909 let arc = Arc::new(T::default());
1911 region.arc_map.insert(raw, arc.clone());
1912
1913 let raw = arc_to_raw(&arc);
1914 unsafe { &mut *raw }.visit("ArcData", &mut region)?;
1915
1916 *self = Arc::downgrade(&arc);
1917 }
1918 }
1919 } else if let Some(arc) = std::sync::Weak::upgrade(self) {
1920 let raw = arc_to_raw(&arc);
1922
1923 let mut index = raw as u64;
1925 index.visit("Id", &mut region)?;
1926
1927 if let Entry::Vacant(entry) = region.arc_map.entry(index) {
1928 entry.insert(arc);
1929 unsafe { &mut *raw }.visit("ArcData", &mut region)?;
1930 }
1931 } else {
1932 let mut index = 0u64;
1933 index.visit("Id", &mut region)?;
1934 }
1935
1936 Ok(())
1937 }
1938}
1939
1940impl<K, V, S> Visit for HashMap<K, V, S>
1941where
1942 K: Visit + Default + Clone + Hash + Eq,
1943 V: Visit + Default,
1944 S: BuildHasher + Clone,
1945{
1946 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1947 let mut region = visitor.enter_region(name)?;
1948
1949 let mut count = self.len() as u32;
1950 count.visit("Count", &mut region)?;
1951
1952 if region.is_reading() {
1953 self.clear();
1954 for i in 0..(count as usize) {
1955 let name = format!("Item{i}");
1956
1957 let mut region = region.enter_region(name.as_str())?;
1958
1959 let mut key = K::default();
1960 key.visit("Key", &mut region)?;
1961
1962 let mut value = V::default();
1963 value.visit("Value", &mut region)?;
1964
1965 self.insert(key, value);
1966 }
1967 } else {
1968 for (i, (key, value)) in self.iter_mut().enumerate() {
1969 let name = format!("Item{i}");
1970
1971 let mut region = region.enter_region(name.as_str())?;
1972
1973 let mut key = key.clone();
1974 key.visit("Key", &mut region)?;
1975
1976 value.visit("Value", &mut region)?;
1977 }
1978 }
1979
1980 Ok(())
1981 }
1982}
1983
1984impl<K, S> Visit for HashSet<K, S>
1985where
1986 K: Visit + Default + Clone + Hash + Eq,
1987 S: BuildHasher + Clone,
1988{
1989 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1990 let mut region = visitor.enter_region(name)?;
1991
1992 let mut count = self.len() as u32;
1993 count.visit("Count", &mut region)?;
1994
1995 if region.is_reading() {
1996 self.clear();
1997 for i in 0..(count as usize) {
1998 let name = format!("Item{i}");
1999
2000 let mut region = region.enter_region(name.as_str())?;
2001
2002 let mut key = K::default();
2003 key.visit("Key", &mut region)?;
2004
2005 self.insert(key);
2006 }
2007 } else {
2008 for (i, mut key) in self.clone().into_iter().enumerate() {
2009 let name = format!("Item{i}");
2010
2011 let mut region = region.enter_region(name.as_str())?;
2012
2013 key.visit("Key", &mut region)?;
2014 }
2015 }
2016
2017 Ok(())
2018 }
2019}
2020
2021impl<T: Default + Visit, const SIZE: usize> Visit for [T; SIZE] {
2022 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
2023 let mut region = visitor.enter_region(name)?;
2024
2025 let mut len = SIZE as u32;
2026 len.visit("Length", &mut region)?;
2027
2028 if region.reading {
2029 if len > SIZE as u32 {
2030 return VisitResult::Err(VisitError::User(format!(
2031 "Not enough space in static array, got {len}, needed {SIZE}!"
2032 )));
2033 }
2034
2035 for index in 0..len {
2036 let region_name = format!("Item{index}");
2037 let mut region = region.enter_region(region_name.as_str())?;
2038 let mut object = T::default();
2039 object.visit("ItemData", &mut region)?;
2040 self[index as usize] = object;
2041 }
2042 } else {
2043 for (index, item) in self.iter_mut().enumerate() {
2044 let region_name = format!("Item{index}");
2045 let mut region = region.enter_region(region_name.as_str())?;
2046 item.visit("ItemData", &mut region)?;
2047 }
2048 }
2049
2050 Ok(())
2051 }
2052}
2053
2054impl Visit for Duration {
2055 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
2056 let mut region = visitor.enter_region(name)?;
2057
2058 let mut secs: u64 = self.as_secs();
2059 let mut nanos: u32 = self.subsec_nanos();
2060
2061 secs.visit("Secs", &mut region)?;
2062 nanos.visit("Nanos", &mut region)?;
2063
2064 if region.is_reading() {
2065 *self = Duration::new(secs, nanos);
2066 }
2067
2068 Ok(())
2069 }
2070}
2071
2072impl Visit for char {
2073 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
2074 let mut bytes = *self as u32;
2075 bytes.visit(name, visitor)?;
2076 if visitor.is_reading() {
2077 *self = char::from_u32(bytes).unwrap();
2078 }
2079 Ok(())
2080 }
2081}
2082
2083impl<T: Visit> Visit for Range<T> {
2084 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
2085 let mut region = visitor.enter_region(name)?;
2086
2087 self.start.visit("Start", &mut region)?;
2088 self.end.visit("End", &mut region)?;
2089
2090 Ok(())
2091 }
2092}
2093
2094impl Visit for usize {
2095 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
2096 let mut this = *self as u64;
2097 this.visit(name, visitor)?;
2098 if visitor.is_reading() {
2099 *self = this as usize;
2100 }
2101 Ok(())
2102 }
2103}
2104
2105impl Visit for isize {
2106 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
2107 let mut this = *self as i64;
2108 this.visit(name, visitor)?;
2109 if visitor.is_reading() {
2110 *self = this as isize;
2111 }
2112 Ok(())
2113 }
2114}
2115
2116#[cfg(test)]
2117mod test {
2118 use crate::visitor::{BinaryBlob, Visit, VisitResult, Visitor};
2119 use std::{fs::File, io::Write, path::Path, rc::Rc};
2120
2121 use super::*;
2122
2123 #[derive(Visit, Default)]
2124 pub struct Model {
2125 data: u64,
2126 }
2127
2128 #[derive(Default)]
2129 pub struct Texture {
2130 data: Vec<u8>,
2131 }
2132
2133 impl Visit for Texture {
2134 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
2135 let mut region = visitor.enter_region(name)?;
2136 let mut proxy = BinaryBlob {
2137 vec: &mut self.data,
2138 };
2139 proxy.visit("Data", &mut region)?;
2140 Ok(())
2141 }
2142 }
2143
2144 #[allow(dead_code)]
2145 #[derive(Visit)]
2146 pub enum ResourceKind {
2147 Unknown,
2148 Model(Model),
2149 Texture(Texture),
2150 }
2151
2152 impl Default for ResourceKind {
2153 fn default() -> Self {
2154 Self::Unknown
2155 }
2156 }
2157
2158 #[derive(Visit)]
2159 struct Resource {
2160 kind: ResourceKind,
2161 data: u16,
2162 }
2163
2164 impl Resource {
2165 fn new(kind: ResourceKind) -> Self {
2166 Self { kind, data: 0 }
2167 }
2168 }
2169
2170 impl Default for Resource {
2171 fn default() -> Self {
2172 Self {
2173 kind: ResourceKind::Unknown,
2174 data: 0,
2175 }
2176 }
2177 }
2178
2179 #[derive(Default, Visit)]
2180 struct Foo {
2181 bar: u64,
2182 shared_resource: Option<Rc<Resource>>,
2183 }
2184
2185 impl Foo {
2186 fn new(resource: Rc<Resource>) -> Self {
2187 Self {
2188 bar: 123,
2189 shared_resource: Some(resource),
2190 }
2191 }
2192 }
2193
2194 #[test]
2195 fn visitor_test() {
2196 let path = Path::new("test.bin");
2197
2198 {
2200 let mut visitor = Visitor::new();
2201 let mut resource = Rc::new(Resource::new(ResourceKind::Model(Model { data: 555 })));
2202 resource.visit("SharedResource", &mut visitor).unwrap();
2203
2204 let mut objects = vec![Foo::new(resource.clone()), Foo::new(resource)];
2205
2206 objects.visit("Objects", &mut visitor).unwrap();
2207
2208 visitor.save_binary(path).unwrap();
2209 if let Ok(mut file) = File::create(Path::new("test.txt")) {
2210 file.write_all(visitor.save_text().as_bytes()).unwrap();
2211 }
2212 }
2213
2214 {
2216 let mut visitor = futures::executor::block_on(Visitor::load_binary(path)).unwrap();
2217 let mut resource: Rc<Resource> = Rc::new(Default::default());
2218 resource.visit("SharedResource", &mut visitor).unwrap();
2219
2220 let mut objects: Vec<Foo> = Vec::new();
2221 objects.visit("Objects", &mut visitor).unwrap();
2222 }
2223 }
2224
2225 #[test]
2226 fn pod_vec_view_from_pod_vec() {
2227 let mut v = Vec::<u8>::new();
2229 let mut v2 = v.clone();
2230 let p = PodVecView::from_pod_vec(&mut v);
2231 assert_eq!(p.type_id, 0_u8);
2232 assert_eq!(p.vec, &mut v2);
2233
2234 let mut v = Vec::<i8>::new();
2236 let p = PodVecView::from_pod_vec(&mut v);
2237 assert_eq!(p.type_id, 1_u8);
2238
2239 let mut v = Vec::<u16>::new();
2241 let p = PodVecView::from_pod_vec(&mut v);
2242 assert_eq!(p.type_id, 2_u8);
2243
2244 let mut v = Vec::<i16>::new();
2246 let p = PodVecView::from_pod_vec(&mut v);
2247 assert_eq!(p.type_id, 3_u8);
2248
2249 let mut v = Vec::<u32>::new();
2251 let p = PodVecView::from_pod_vec(&mut v);
2252 assert_eq!(p.type_id, 4_u8);
2253
2254 let mut v = Vec::<i32>::new();
2256 let p = PodVecView::from_pod_vec(&mut v);
2257 assert_eq!(p.type_id, 5_u8);
2258
2259 let mut v = Vec::<u64>::new();
2261 let p = PodVecView::from_pod_vec(&mut v);
2262 assert_eq!(p.type_id, 6_u8);
2263
2264 let mut v = Vec::<i64>::new();
2266 let p = PodVecView::from_pod_vec(&mut v);
2267 assert_eq!(p.type_id, 7_u8);
2268
2269 let mut v = Vec::<f32>::new();
2271 let p = PodVecView::from_pod_vec(&mut v);
2272 assert_eq!(p.type_id, 8_u8);
2273
2274 let mut v = Vec::<f64>::new();
2276 let p = PodVecView::from_pod_vec(&mut v);
2277 assert_eq!(p.type_id, 9_u8);
2278 }
2279
2280 #[test]
2281 fn field_kind_as_string() {
2282 assert_eq!(
2283 FieldKind::Bool(true).as_string(),
2284 "<bool = true>, ".to_string()
2285 );
2286 assert_eq!(
2287 FieldKind::BinaryBlob(Vec::<u8>::new()).as_string(),
2288 "<data = >, ".to_string()
2289 );
2290
2291 assert_eq!(FieldKind::F32(0.0).as_string(), "<f32 = 0>, ".to_string());
2292 assert_eq!(FieldKind::F64(0.0).as_string(), "<f64 = 0>, ".to_string());
2293
2294 assert_eq!(FieldKind::I8(0).as_string(), "<i8 = 0>, ".to_string());
2295 assert_eq!(FieldKind::I16(0).as_string(), "<i16 = 0>, ".to_string());
2296 assert_eq!(FieldKind::I32(0).as_string(), "<i32 = 0>, ".to_string());
2297 assert_eq!(FieldKind::I64(0).as_string(), "<i64 = 0>, ".to_string());
2298
2299 assert_eq!(
2300 FieldKind::Matrix2(Matrix2::default()).as_string(),
2301 "<mat2 = 0; 0; 0; 0; ".to_string()
2302 );
2303 assert_eq!(
2304 FieldKind::Matrix3(Matrix3::default()).as_string(),
2305 "<mat3 = 0; 0; 0; 0; 0; 0; 0; 0; 0; ".to_string()
2306 );
2307 assert_eq!(
2308 FieldKind::Matrix4(Matrix4::default()).as_string(),
2309 "<mat4 = 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; ".to_string()
2310 );
2311 assert_eq!(
2312 FieldKind::PodArray {
2313 type_id: 0,
2314 element_size: 0,
2315 bytes: Vec::new()
2316 }
2317 .as_string(),
2318 "<podarray = 0; 0; []>".to_string()
2319 );
2320
2321 assert_eq!(FieldKind::U8(0).as_string(), "<u8 = 0>, ".to_string());
2322 assert_eq!(FieldKind::U16(0).as_string(), "<u16 = 0>, ".to_string());
2323 assert_eq!(FieldKind::U32(0).as_string(), "<u32 = 0>, ".to_string());
2324 assert_eq!(FieldKind::U64(0).as_string(), "<u64 = 0>, ".to_string());
2325
2326 assert_eq!(
2327 FieldKind::UnitComplex(UnitComplex::default()).as_string(),
2328 "<complex = 1; 0>, ".to_string()
2329 );
2330 assert_eq!(
2331 FieldKind::UnitQuaternion(UnitQuaternion::default()).as_string(),
2332 "<quat = 0; 0; 0; 1>, ".to_string()
2333 );
2334 assert_eq!(
2335 FieldKind::Uuid(Uuid::default()).as_string(),
2336 "<uuid = 00000000-0000-0000-0000-000000000000".to_string()
2337 );
2338
2339 assert_eq!(
2340 FieldKind::Vector2F32(Vector2::new(0.0, 0.0)).as_string(),
2341 "<vec2f32 = 0; 0>, ".to_string()
2342 );
2343 assert_eq!(
2344 FieldKind::Vector2F64(Vector2::new(0.0, 0.0)).as_string(),
2345 "<vec2f64 = 0; 0>, ".to_string()
2346 );
2347 assert_eq!(
2348 FieldKind::Vector2U8(Vector2::new(0, 0)).as_string(),
2349 "<vec2u8 = 0; 0>, ".to_string()
2350 );
2351 assert_eq!(
2352 FieldKind::Vector2U16(Vector2::new(0, 0)).as_string(),
2353 "<vec2u16 = 0; 0>, ".to_string()
2354 );
2355 assert_eq!(
2356 FieldKind::Vector2U32(Vector2::new(0, 0)).as_string(),
2357 "<vec2u32 = 0; 0>, ".to_string()
2358 );
2359 assert_eq!(
2360 FieldKind::Vector2U64(Vector2::new(0, 0)).as_string(),
2361 "<vec2u64 = 0; 0>, ".to_string()
2362 );
2363 assert_eq!(
2364 FieldKind::Vector2I8(Vector2::new(0, 0)).as_string(),
2365 "<vec2i8 = 0; 0>, ".to_string()
2366 );
2367 assert_eq!(
2368 FieldKind::Vector2I16(Vector2::new(0, 0)).as_string(),
2369 "<vec2i16 = 0; 0>, ".to_string()
2370 );
2371 assert_eq!(
2372 FieldKind::Vector2I32(Vector2::new(0, 0)).as_string(),
2373 "<vec2i32 = 0; 0>, ".to_string()
2374 );
2375 assert_eq!(
2376 FieldKind::Vector2I64(Vector2::new(0, 0)).as_string(),
2377 "<vec2i64 = 0; 0>, ".to_string()
2378 );
2379
2380 assert_eq!(
2381 FieldKind::Vector3F32(Vector3::new(0.0, 0.0, 0.0)).as_string(),
2382 "<vec3f32 = 0; 0; 0>, ".to_string()
2383 );
2384 assert_eq!(
2385 FieldKind::Vector3F64(Vector3::new(0.0, 0.0, 0.0)).as_string(),
2386 "<vec3f64 = 0; 0; 0>, ".to_string()
2387 );
2388 assert_eq!(
2389 FieldKind::Vector3U8(Vector3::new(0, 0, 0)).as_string(),
2390 "<vec3u8 = 0; 0; 0>, ".to_string()
2391 );
2392 assert_eq!(
2393 FieldKind::Vector3U16(Vector3::new(0, 0, 0)).as_string(),
2394 "<vec3u16 = 0; 0; 0>, ".to_string()
2395 );
2396 assert_eq!(
2397 FieldKind::Vector3U32(Vector3::new(0, 0, 0)).as_string(),
2398 "<vec3u32 = 0; 0; 0>, ".to_string()
2399 );
2400 assert_eq!(
2401 FieldKind::Vector3U64(Vector3::new(0, 0, 0)).as_string(),
2402 "<vec3u64 = 0; 0; 0>, ".to_string()
2403 );
2404 assert_eq!(
2405 FieldKind::Vector3I8(Vector3::new(0, 0, 0)).as_string(),
2406 "<vec3i8 = 0; 0; 0>, ".to_string()
2407 );
2408 assert_eq!(
2409 FieldKind::Vector3I16(Vector3::new(0, 0, 0)).as_string(),
2410 "<vec3i16 = 0; 0; 0>, ".to_string()
2411 );
2412 assert_eq!(
2413 FieldKind::Vector3I32(Vector3::new(0, 0, 0)).as_string(),
2414 "<vec3i32 = 0; 0; 0>, ".to_string()
2415 );
2416 assert_eq!(
2417 FieldKind::Vector3I64(Vector3::new(0, 0, 0)).as_string(),
2418 "<vec3i64 = 0; 0; 0>, ".to_string()
2419 );
2420
2421 assert_eq!(
2422 FieldKind::Vector4F32(Vector4::new(0.0, 0.0, 0.0, 0.0)).as_string(),
2423 "<vec4f32 = 0; 0; 0; 0>, ".to_string()
2424 );
2425 assert_eq!(
2426 FieldKind::Vector4F64(Vector4::new(0.0, 0.0, 0.0, 0.0)).as_string(),
2427 "<vec4f64 = 0; 0; 0; 0>, ".to_string()
2428 );
2429 assert_eq!(
2430 FieldKind::Vector4U8(Vector4::new(0, 0, 0, 0)).as_string(),
2431 "<vec4u8 = 0; 0; 0; 0>, ".to_string()
2432 );
2433 assert_eq!(
2434 FieldKind::Vector4U16(Vector4::new(0, 0, 0, 0)).as_string(),
2435 "<vec4u16 = 0; 0; 0; 0>, ".to_string()
2436 );
2437 assert_eq!(
2438 FieldKind::Vector4U32(Vector4::new(0, 0, 0, 0)).as_string(),
2439 "<vec4u32 = 0; 0; 0; 0>, ".to_string()
2440 );
2441 assert_eq!(
2442 FieldKind::Vector4U64(Vector4::new(0, 0, 0, 0)).as_string(),
2443 "<vec4u64 = 0; 0; 0; 0>, ".to_string()
2444 );
2445 assert_eq!(
2446 FieldKind::Vector4I8(Vector4::new(0, 0, 0, 0)).as_string(),
2447 "<vec4i8 = 0; 0; 0; 0>, ".to_string()
2448 );
2449 assert_eq!(
2450 FieldKind::Vector4I16(Vector4::new(0, 0, 0, 0)).as_string(),
2451 "<vec4i16 = 0; 0; 0; 0>, ".to_string()
2452 );
2453 assert_eq!(
2454 FieldKind::Vector4I32(Vector4::new(0, 0, 0, 0)).as_string(),
2455 "<vec4i32 = 0; 0; 0; 0>, ".to_string()
2456 );
2457 assert_eq!(
2458 FieldKind::Vector4I64(Vector4::new(0, 0, 0, 0)).as_string(),
2459 "<vec4i64 = 0; 0; 0; 0>, ".to_string()
2460 );
2461 }
2462}