rg3d_core/
visitor.rs

1//! Visitor is a tree-based serializer/deserializer.
2//!
3//! # Overview
4//!
5//! Visitor uses tree to create structured storage of data. Basic unit is a *node* - it is a container
6//! for data fields. Each node has name, handle to parent, set of handles to children nodes and some
7//! container for data fields. Data field is tuple of name and value, value can be any of simple Rust
8//! types and some of basic structures of the crate. Main criteria of what could be the field and what
9//! not is the ability to be represented as set of bytes without any aliasing issues.
10
11pub use rg3d_core_derive::Visit;
12
13pub mod prelude {
14    //! Types to use `#[derive(Visit)]`
15    pub use super::{Visit, VisitError, VisitResult, Visitor};
16}
17
18use crate::{
19    algebra::{
20        Complex, Matrix2, Matrix3, Matrix4, Quaternion, UnitComplex, UnitQuaternion, Vector2,
21        Vector3, Vector4,
22    },
23    io::{self, FileLoadError},
24    pool::{Handle, Pool},
25    replace_slashes,
26};
27
28use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
29use fxhash::FxHashMap;
30use std::collections::HashMap;
31use std::{
32    any::Any,
33    cell::{Cell, RefCell},
34    collections::hash_map::Entry,
35    fmt::{Display, Formatter},
36    fs::File,
37    hash::Hash,
38    io::{BufWriter, Cursor, Read, Write},
39    ops::{DerefMut, Range},
40    path::{Path, PathBuf},
41    rc::Rc,
42    string::FromUtf8Error,
43    sync::{Arc, Mutex, RwLock},
44};
45use uuid::Uuid;
46
47pub enum FieldKind {
48    Bool(bool),
49    U8(u8),
50    I8(i8),
51    U16(u16),
52    I16(i16),
53    U32(u32),
54    I32(i32),
55    U64(u64),
56    I64(i64),
57    F32(f32),
58    F64(f64),
59    Vector3(Vector3<f32>),
60    UnitQuaternion(UnitQuaternion<f32>),
61    Matrix4(Matrix4<f32>),
62    Data(Vec<u8>),
63    Matrix3(Matrix3<f32>),
64    Vector2(Vector2<f32>),
65    Vector4(Vector4<f32>),
66    Uuid(Uuid),
67    UnitComplex(UnitComplex<f32>),
68    PodArray {
69        type_id: u8,
70        element_size: u32,
71        bytes: Vec<u8>,
72    },
73    Matrix2(Matrix2<f32>),
74}
75
76pub trait Pod: Copy {
77    fn type_id() -> u8;
78}
79
80impl Pod for u8 {
81    fn type_id() -> u8 {
82        0
83    }
84}
85
86impl Pod for i8 {
87    fn type_id() -> u8 {
88        1
89    }
90}
91
92impl Pod for u16 {
93    fn type_id() -> u8 {
94        2
95    }
96}
97
98impl Pod for i16 {
99    fn type_id() -> u8 {
100        3
101    }
102}
103
104impl Pod for u32 {
105    fn type_id() -> u8 {
106        4
107    }
108}
109
110impl Pod for i32 {
111    fn type_id() -> u8 {
112        5
113    }
114}
115
116impl Pod for u64 {
117    fn type_id() -> u8 {
118        6
119    }
120}
121
122impl Pod for i64 {
123    fn type_id() -> u8 {
124        7
125    }
126}
127
128impl Pod for f32 {
129    fn type_id() -> u8 {
130        8
131    }
132}
133
134impl Pod for f64 {
135    fn type_id() -> u8 {
136        9
137    }
138}
139
140pub struct PodVecView<'a, T: Pod> {
141    type_id: u8,
142    vec: &'a mut Vec<T>,
143}
144
145impl<'a, T: Pod> PodVecView<'a, T> {
146    pub fn from_pod_vec(vec: &'a mut Vec<T>) -> Self {
147        Self {
148            type_id: T::type_id(),
149            vec,
150        }
151    }
152}
153
154impl<'a, T: Pod> Visit for PodVecView<'a, T> {
155    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
156        if visitor.reading {
157            if let Some(field) = visitor.find_field(name) {
158                match &field.kind {
159                    FieldKind::PodArray {
160                        type_id,
161                        element_size,
162                        bytes,
163                    } => {
164                        if *type_id == self.type_id {
165                            let mut owned_bytes = bytes.clone();
166                            let len = owned_bytes.len() / (*element_size as usize);
167                            *self.vec = unsafe {
168                                Vec::from_raw_parts(owned_bytes.as_mut_ptr() as *mut T, len, len)
169                            };
170                            std::mem::forget(owned_bytes);
171                            Ok(())
172                        } else {
173                            Err(VisitError::TypeMismatch)
174                        }
175                    }
176                    _ => Err(VisitError::FieldTypeDoesNotMatch),
177                }
178            } else {
179                Err(VisitError::FieldDoesNotExist(name.to_owned()))
180            }
181        } else if visitor.find_field(name).is_some() {
182            Err(VisitError::FieldAlreadyExists(name.to_owned()))
183        } else {
184            let node = visitor.current_node();
185            node.fields.push(Field::new(
186                name,
187                FieldKind::PodArray {
188                    type_id: T::type_id(),
189                    element_size: std::mem::size_of::<T>() as u32,
190                    bytes: unsafe {
191                        let mut data = self.vec.clone();
192                        let bytes = Vec::from_raw_parts(
193                            data.as_mut_ptr() as *mut u8,
194                            data.len() * std::mem::size_of::<T>(),
195                            data.capacity() * std::mem::size_of::<T>(),
196                        );
197                        std::mem::forget(data);
198                        bytes
199                    },
200                },
201            ));
202            Ok(())
203        }
204    }
205}
206
207impl FieldKind {
208    fn as_string(&self) -> String {
209        match self {
210            Self::Bool(data) => format!("<bool = {}>, ", data),
211            Self::U8(data) => format!("<u8 = {}>, ", data),
212            Self::I8(data) => format!("<i8 = {}>, ", data),
213            Self::U16(data) => format!("<u16 = {}>, ", data),
214            Self::I16(data) => format!("<i16 = {}>, ", data),
215            Self::U32(data) => format!("<u32 = {}>, ", data),
216            Self::I32(data) => format!("<i32 = {}>, ", data),
217            Self::U64(data) => format!("<u64 = {}>, ", data),
218            Self::I64(data) => format!("<i64 = {}>, ", data),
219            Self::F32(data) => format!("<f32 = {}>, ", data),
220            Self::F64(data) => format!("<f64 = {}>, ", data),
221            Self::Vector3(data) => format!("<vec3 = {}; {}; {}>, ", data.x, data.y, data.z),
222            Self::UnitQuaternion(data) => {
223                format!("<quat = {}; {}; {}; {}>, ", data.i, data.j, data.k, data.w)
224            }
225            Self::Matrix4(data) => {
226                let mut out = String::from("<mat4 = ");
227                for f in data.iter() {
228                    out += format!("{}; ", f).as_str();
229                }
230                out
231            }
232            Self::Data(data) => {
233                let out = match String::from_utf8(data.clone()) {
234                    Ok(s) => s,
235                    Err(_) => base64::encode(data),
236                };
237                format!("<data = {}>, ", out)
238            }
239            Self::Matrix3(data) => {
240                let mut out = String::from("<mat3 = ");
241                for f in data.iter() {
242                    out += format!("{}; ", f).as_str();
243                }
244                out
245            }
246            Self::Vector2(data) => format!("<vec2 = {}; {}>, ", data.x, data.y),
247            Self::Vector4(data) => {
248                format!("<vec4 = {}; {}; {}; {}>, ", data.x, data.y, data.z, data.w)
249            }
250            Self::Uuid(uuid) => uuid.to_string(),
251            Self::UnitComplex(data) => {
252                format!("<complex = {}; {}>, ", data.re, data.im)
253            }
254            FieldKind::PodArray {
255                type_id,
256                element_size,
257                bytes,
258            } => {
259                let base64_encoded = base64::encode(bytes);
260                format!(
261                    "<podarray = {}; {}; [{}]>",
262                    type_id, element_size, base64_encoded
263                )
264            }
265            Self::Matrix2(data) => {
266                let mut out = String::from("<mat2 = ");
267                for f in data.iter() {
268                    out += format!("{}; ", f).as_str();
269                }
270                out
271            }
272        }
273    }
274}
275
276macro_rules! impl_field_data {
277    ($type_name:ty, $($kind:tt)*) => {
278        impl Visit for $type_name {
279            fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
280                if visitor.reading {
281                    if let Some(field) = visitor.find_field(name) {
282                        match field.kind {
283                            $($kind)*(data) => {
284                                *self = data.clone();
285                                Ok(())
286                            },
287                            _ => Err(VisitError::FieldTypeDoesNotMatch)
288                        }
289                    } else {
290                        Err(VisitError::FieldDoesNotExist(name.to_owned()))
291                    }
292                } else if visitor.find_field(name).is_some() {
293                    Err(VisitError::FieldAlreadyExists(name.to_owned()))
294                } else {
295                    let node = visitor.current_node();
296                    node.fields.push(Field::new(name, $($kind)*(self.clone())));
297                    Ok(())
298                }
299            }
300        }
301    };
302}
303
304/// Proxy struct for plain data, we can't use Vec<u8> directly,
305/// because it will serialize each byte as separate node.
306pub struct Data<'a> {
307    vec: &'a mut Vec<u8>,
308}
309
310impl_field_data!(u64, FieldKind::U64);
311impl_field_data!(i64, FieldKind::I64);
312impl_field_data!(u32, FieldKind::U32);
313impl_field_data!(i32, FieldKind::I32);
314impl_field_data!(u16, FieldKind::U16);
315impl_field_data!(i16, FieldKind::I16);
316impl_field_data!(u8, FieldKind::U8);
317impl_field_data!(i8, FieldKind::I8);
318impl_field_data!(f32, FieldKind::F32);
319impl_field_data!(f64, FieldKind::F64);
320impl_field_data!(Vector3<f32>, FieldKind::Vector3);
321impl_field_data!(UnitQuaternion<f32>, FieldKind::UnitQuaternion);
322impl_field_data!(Matrix4<f32>, FieldKind::Matrix4);
323impl_field_data!(bool, FieldKind::Bool);
324impl_field_data!(Matrix3<f32>, FieldKind::Matrix3);
325impl_field_data!(Vector2<f32>, FieldKind::Vector2);
326impl_field_data!(Vector4<f32>, FieldKind::Vector4);
327impl_field_data!(Uuid, FieldKind::Uuid);
328impl_field_data!(UnitComplex<f32>, FieldKind::UnitComplex);
329impl_field_data!(Matrix2<f32>, FieldKind::Matrix2);
330
331impl<'a> Visit for Data<'a> {
332    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
333        if visitor.reading {
334            if let Some(field) = visitor.find_field(name) {
335                match &field.kind {
336                    FieldKind::Data(data) => {
337                        *self.vec = data.clone();
338                        Ok(())
339                    }
340                    _ => Err(VisitError::FieldTypeDoesNotMatch),
341                }
342            } else {
343                Err(VisitError::FieldDoesNotExist(name.to_owned()))
344            }
345        } else if visitor.find_field(name).is_some() {
346            Err(VisitError::FieldAlreadyExists(name.to_owned()))
347        } else {
348            let node = visitor.current_node();
349            node.fields
350                .push(Field::new(name, FieldKind::Data(self.vec.clone())));
351            Ok(())
352        }
353    }
354}
355
356pub struct Field {
357    name: String,
358    kind: FieldKind,
359}
360
361#[derive(Debug)]
362pub enum VisitError {
363    Io(std::io::Error),
364    UnknownFieldType(u8),
365    FieldDoesNotExist(String),
366    FieldAlreadyExists(String),
367    RegionAlreadyExists(String),
368    InvalidCurrentNode,
369    FieldTypeDoesNotMatch,
370    RegionDoesNotExist(String),
371    NoActiveNode,
372    NotSupportedFormat,
373    InvalidName,
374    TypeMismatch,
375    RefCellAlreadyMutableBorrowed,
376    User(String),
377    UnexpectedRcNullIndex,
378    PoisonedMutex,
379    FileLoadError(FileLoadError),
380}
381
382impl Display for VisitError {
383    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
384        match self {
385            Self::Io(io) => write!(f, "io error: {}", io),
386            Self::UnknownFieldType(type_index) => write!(f, "unknown field type {}", type_index),
387            Self::FieldDoesNotExist(name) => write!(f, "field does not exists {}", name),
388            Self::FieldAlreadyExists(name) => write!(f, "field already exists {}", name),
389            Self::RegionAlreadyExists(name) => write!(f, "region already exists {}", name),
390            Self::InvalidCurrentNode => write!(f, "invalid current node"),
391            Self::FieldTypeDoesNotMatch => write!(f, "field type does not match"),
392            Self::RegionDoesNotExist(name) => write!(f, "region does not exists {}", name),
393            Self::NoActiveNode => write!(f, "no active node"),
394            Self::NotSupportedFormat => write!(f, "not supported format"),
395            Self::InvalidName => write!(f, "invalid name"),
396            Self::TypeMismatch => write!(f, "type mismatch"),
397            Self::RefCellAlreadyMutableBorrowed => write!(f, "ref cell already mutable borrowed"),
398            Self::User(msg) => write!(f, "user defined error: {}", msg),
399            Self::UnexpectedRcNullIndex => write!(f, "unexpected rc null index"),
400            Self::PoisonedMutex => write!(f, "attempt to lock poisoned mutex"),
401            Self::FileLoadError(e) => write!(f, "file load error: {:?}", e),
402        }
403    }
404}
405
406impl<'a, T> From<std::sync::PoisonError<std::sync::MutexGuard<'a, T>>> for VisitError {
407    fn from(_: std::sync::PoisonError<std::sync::MutexGuard<'a, T>>) -> Self {
408        Self::PoisonedMutex
409    }
410}
411
412impl<'a, T> From<std::sync::PoisonError<&mut T>> for VisitError {
413    fn from(_: std::sync::PoisonError<&mut T>) -> Self {
414        Self::PoisonedMutex
415    }
416}
417
418impl<'a, T> From<std::sync::PoisonError<std::sync::RwLockWriteGuard<'_, T>>> for VisitError {
419    fn from(_: std::sync::PoisonError<std::sync::RwLockWriteGuard<'_, T>>) -> Self {
420        Self::PoisonedMutex
421    }
422}
423
424impl From<std::io::Error> for VisitError {
425    fn from(io_err: std::io::Error) -> Self {
426        Self::Io(io_err)
427    }
428}
429
430impl From<FromUtf8Error> for VisitError {
431    fn from(_: FromUtf8Error) -> Self {
432        Self::InvalidName
433    }
434}
435
436impl From<String> for VisitError {
437    fn from(s: String) -> Self {
438        Self::User(s)
439    }
440}
441
442impl From<FileLoadError> for VisitError {
443    fn from(e: FileLoadError) -> Self {
444        Self::FileLoadError(e)
445    }
446}
447
448pub type VisitResult = Result<(), VisitError>;
449
450impl Field {
451    pub fn new(name: &str, kind: FieldKind) -> Self {
452        Self {
453            name: name.to_owned(),
454            kind,
455        }
456    }
457
458    fn save(field: &Field, file: &mut dyn Write) -> VisitResult {
459        let name = field.name.as_bytes();
460        file.write_u32::<LittleEndian>(name.len() as u32)?;
461        file.write_all(name)?;
462        match &field.kind {
463            FieldKind::U8(data) => {
464                file.write_u8(1)?;
465                file.write_u8(*data)?;
466            }
467            FieldKind::I8(data) => {
468                file.write_i8(2)?;
469                file.write_i8(*data)?;
470            }
471            FieldKind::U16(data) => {
472                file.write_u8(3)?;
473                file.write_u16::<LittleEndian>(*data)?;
474            }
475            FieldKind::I16(data) => {
476                file.write_u8(4)?;
477                file.write_i16::<LittleEndian>(*data)?;
478            }
479            FieldKind::U32(data) => {
480                file.write_u8(5)?;
481                file.write_u32::<LittleEndian>(*data)?;
482            }
483            FieldKind::I32(data) => {
484                file.write_u8(6)?;
485                file.write_i32::<LittleEndian>(*data)?;
486            }
487            FieldKind::U64(data) => {
488                file.write_u8(7)?;
489                file.write_u64::<LittleEndian>(*data)?;
490            }
491            FieldKind::I64(data) => {
492                file.write_u8(8)?;
493                file.write_i64::<LittleEndian>(*data)?;
494            }
495            FieldKind::F32(data) => {
496                file.write_u8(9)?;
497                file.write_f32::<LittleEndian>(*data)?;
498            }
499            FieldKind::F64(data) => {
500                file.write_u8(10)?;
501                file.write_f64::<LittleEndian>(*data)?;
502            }
503            FieldKind::Vector3(data) => {
504                file.write_u8(11)?;
505                file.write_f32::<LittleEndian>(data.x)?;
506                file.write_f32::<LittleEndian>(data.y)?;
507                file.write_f32::<LittleEndian>(data.z)?;
508            }
509            FieldKind::UnitQuaternion(data) => {
510                file.write_u8(12)?;
511                file.write_f32::<LittleEndian>(data.i)?;
512                file.write_f32::<LittleEndian>(data.j)?;
513                file.write_f32::<LittleEndian>(data.k)?;
514                file.write_f32::<LittleEndian>(data.w)?;
515            }
516            FieldKind::Matrix4(data) => {
517                file.write_u8(13)?;
518                for f in data.iter() {
519                    file.write_f32::<LittleEndian>(*f)?;
520                }
521            }
522            FieldKind::Data(data) => {
523                file.write_u8(14)?;
524                file.write_u32::<LittleEndian>(data.len() as u32)?;
525                file.write_all(data.as_slice())?;
526            }
527            FieldKind::Bool(data) => {
528                file.write_u8(15)?;
529                file.write_u8(if *data { 1 } else { 0 })?;
530            }
531            FieldKind::Matrix3(data) => {
532                file.write_u8(16)?;
533                for f in data.iter() {
534                    file.write_f32::<LittleEndian>(*f)?;
535                }
536            }
537            FieldKind::Vector2(data) => {
538                file.write_u8(17)?;
539                file.write_f32::<LittleEndian>(data.x)?;
540                file.write_f32::<LittleEndian>(data.y)?;
541            }
542            FieldKind::Vector4(data) => {
543                file.write_u8(18)?;
544                file.write_f32::<LittleEndian>(data.x)?;
545                file.write_f32::<LittleEndian>(data.y)?;
546                file.write_f32::<LittleEndian>(data.z)?;
547                file.write_f32::<LittleEndian>(data.w)?;
548            }
549            FieldKind::Uuid(uuid) => {
550                file.write_u8(19)?;
551                file.write_all(uuid.as_bytes())?;
552            }
553            FieldKind::UnitComplex(c) => {
554                file.write_u8(20)?;
555                file.write_f32::<LittleEndian>(c.re)?;
556                file.write_f32::<LittleEndian>(c.im)?;
557            }
558            FieldKind::PodArray {
559                type_id,
560                element_size,
561                bytes,
562            } => {
563                file.write_u8(21)?;
564                file.write_u8(*type_id)?;
565                file.write_u32::<LittleEndian>(*element_size)?;
566                file.write_u64::<LittleEndian>(bytes.len() as u64)?;
567                file.write_all(bytes)?;
568            }
569            FieldKind::Matrix2(data) => {
570                file.write_u8(22)?;
571                for f in data.iter() {
572                    file.write_f32::<LittleEndian>(*f)?;
573                }
574            }
575        }
576        Ok(())
577    }
578
579    fn load(file: &mut dyn Read) -> Result<Field, VisitError> {
580        let name_len = file.read_u32::<LittleEndian>()? as usize;
581        let mut raw_name = vec![Default::default(); name_len];
582        file.read_exact(raw_name.as_mut_slice())?;
583        let id = file.read_u8()?;
584        Ok(Field::new(
585            String::from_utf8(raw_name)?.as_str(),
586            match id {
587                1 => FieldKind::U8(file.read_u8()?),
588                2 => FieldKind::I8(file.read_i8()?),
589                3 => FieldKind::U16(file.read_u16::<LittleEndian>()?),
590                4 => FieldKind::I16(file.read_i16::<LittleEndian>()?),
591                5 => FieldKind::U32(file.read_u32::<LittleEndian>()?),
592                6 => FieldKind::I32(file.read_i32::<LittleEndian>()?),
593                7 => FieldKind::U64(file.read_u64::<LittleEndian>()?),
594                8 => FieldKind::I64(file.read_i64::<LittleEndian>()?),
595                9 => FieldKind::F32(file.read_f32::<LittleEndian>()?),
596                10 => FieldKind::F64(file.read_f64::<LittleEndian>()?),
597                11 => FieldKind::Vector3({
598                    let x = file.read_f32::<LittleEndian>()?;
599                    let y = file.read_f32::<LittleEndian>()?;
600                    let z = file.read_f32::<LittleEndian>()?;
601                    Vector3::new(x, y, z)
602                }),
603                12 => FieldKind::UnitQuaternion({
604                    let x = file.read_f32::<LittleEndian>()?;
605                    let y = file.read_f32::<LittleEndian>()?;
606                    let z = file.read_f32::<LittleEndian>()?;
607                    let w = file.read_f32::<LittleEndian>()?;
608                    UnitQuaternion::new_normalize(Quaternion::new(w, x, y, z))
609                }),
610                13 => FieldKind::Matrix4({
611                    let mut f = [0.0f32; 16];
612                    for n in &mut f {
613                        *n = file.read_f32::<LittleEndian>()?;
614                    }
615                    Matrix4::from_row_slice(&f)
616                }),
617                14 => FieldKind::Data({
618                    let len = file.read_u32::<LittleEndian>()? as usize;
619                    let mut vec = vec![Default::default(); len];
620                    file.read_exact(vec.as_mut_slice())?;
621                    vec
622                }),
623                15 => FieldKind::Bool(file.read_u8()? != 0),
624                16 => FieldKind::Matrix3({
625                    let mut f = [0.0f32; 9];
626                    for n in &mut f {
627                        *n = file.read_f32::<LittleEndian>()?;
628                    }
629                    Matrix3::from_row_slice(&f)
630                }),
631                17 => FieldKind::Vector2({
632                    let x = file.read_f32::<LittleEndian>()?;
633                    let y = file.read_f32::<LittleEndian>()?;
634                    Vector2::new(x, y)
635                }),
636                18 => FieldKind::Vector4({
637                    let x = file.read_f32::<LittleEndian>()?;
638                    let y = file.read_f32::<LittleEndian>()?;
639                    let z = file.read_f32::<LittleEndian>()?;
640                    let w = file.read_f32::<LittleEndian>()?;
641                    Vector4::new(x, y, z, w)
642                }),
643                19 => FieldKind::Uuid({
644                    let mut bytes = uuid::Bytes::default();
645                    file.read_exact(&mut bytes)?;
646                    Uuid::from_bytes(bytes)
647                }),
648                20 => FieldKind::UnitComplex({
649                    let re = file.read_f32::<LittleEndian>()?;
650                    let im = file.read_f32::<LittleEndian>()?;
651                    UnitComplex::from_complex(Complex::new(re, im))
652                }),
653                21 => {
654                    let type_id = file.read_u8()?;
655                    let element_size = file.read_u32::<LittleEndian>()?;
656                    let data_size = file.read_u64::<LittleEndian>()?;
657                    let mut bytes = vec![0; data_size as usize];
658                    file.read_exact(&mut bytes)?;
659                    FieldKind::PodArray {
660                        type_id,
661                        element_size,
662                        bytes,
663                    }
664                }
665                22 => FieldKind::Matrix2({
666                    let mut f = [0.0f32; 3];
667                    for n in &mut f {
668                        *n = file.read_f32::<LittleEndian>()?;
669                    }
670                    Matrix2::from_row_slice(&f)
671                }),
672                _ => return Err(VisitError::UnknownFieldType(id)),
673            },
674        ))
675    }
676
677    fn as_string(&self) -> String {
678        format!("{}{}", self.name, self.kind.as_string())
679    }
680}
681
682pub struct Node {
683    name: String,
684    fields: Vec<Field>,
685    parent: Handle<Node>,
686    children: Vec<Handle<Node>>,
687}
688
689impl Node {
690    fn new(name: &str, parent: Handle<Node>) -> Self {
691        Self {
692            name: name.to_owned(),
693            fields: Vec::new(),
694            parent,
695            children: Vec::new(),
696        }
697    }
698}
699
700impl Default for Node {
701    fn default() -> Self {
702        Self {
703            name: String::new(),
704            fields: Vec::new(),
705            parent: Handle::NONE,
706            children: Vec::new(),
707        }
708    }
709}
710
711pub struct Visitor {
712    nodes: Pool<Node>,
713    rc_map: FxHashMap<u64, Rc<dyn Any>>,
714    arc_map: FxHashMap<u64, Arc<dyn Any + Send + Sync>>,
715    reading: bool,
716    current_node: Handle<Node>,
717    root: Handle<Node>,
718}
719
720pub trait Visit {
721    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult;
722}
723
724impl Default for Visitor {
725    fn default() -> Self {
726        Self::new()
727    }
728}
729
730impl Visitor {
731    const MAGIC: &'static str = "RG3D";
732
733    pub fn new() -> Self {
734        let mut nodes = Pool::new();
735        let root = nodes.spawn(Node::new("__ROOT__", Handle::NONE));
736        Self {
737            nodes,
738            rc_map: FxHashMap::default(),
739            arc_map: FxHashMap::default(),
740            reading: false,
741            current_node: root,
742            root,
743        }
744    }
745
746    fn find_field(&mut self, name: &str) -> Option<&mut Field> {
747        let node = self.nodes.borrow_mut(self.current_node);
748        for field in node.fields.iter_mut() {
749            if field.name == name {
750                return Some(field);
751            }
752        }
753        None
754    }
755
756    pub fn is_reading(&self) -> bool {
757        self.reading
758    }
759
760    fn current_node(&mut self) -> &mut Node {
761        self.nodes.borrow_mut(self.current_node)
762    }
763
764    pub fn enter_region(&mut self, name: &str) -> VisitResult {
765        let node = self.nodes.borrow(self.current_node);
766        if self.reading {
767            let mut region = Handle::NONE;
768            for child_handle in node.children.iter() {
769                let child = self.nodes.borrow(*child_handle);
770                if child.name == name {
771                    region = *child_handle;
772                    break;
773                }
774            }
775            if region.is_some() {
776                self.current_node = region;
777                Ok(())
778            } else {
779                Err(VisitError::RegionDoesNotExist(name.to_owned()))
780            }
781        } else {
782            // Make sure that node does not exists already.
783            for child_handle in node.children.iter() {
784                let child = self.nodes.borrow(*child_handle);
785                if child.name == name {
786                    return Err(VisitError::RegionAlreadyExists(name.to_owned()));
787                }
788            }
789
790            let node_handle = self.nodes.spawn(Node::new(name, self.current_node));
791            self.nodes
792                .borrow_mut(self.current_node)
793                .children
794                .push(node_handle);
795            self.current_node = node_handle;
796
797            Ok(())
798        }
799    }
800
801    pub fn leave_region(&mut self) -> VisitResult {
802        self.current_node = self.nodes.borrow(self.current_node).parent;
803        if self.current_node.is_none() {
804            Err(VisitError::NoActiveNode)
805        } else {
806            Ok(())
807        }
808    }
809
810    fn print_node(&self, node_handle: Handle<Node>, nesting: usize, out_string: &mut String) {
811        let offset = (0..nesting).map(|_| "\t").collect::<String>();
812        let node = self.nodes.borrow(node_handle);
813        *out_string += format!(
814            "{}{}[Fields={}, Children={}]: ",
815            offset,
816            node.name,
817            node.fields.len(),
818            node.children.len()
819        )
820        .as_str();
821        for field in node.fields.iter() {
822            *out_string += field.as_string().as_str();
823        }
824
825        *out_string += "\n";
826
827        for child_handle in node.children.iter() {
828            self.print_node(*child_handle, nesting + 1, out_string);
829        }
830    }
831
832    pub fn save_text(&self) -> String {
833        let mut out_string = String::new();
834        self.print_node(self.root, 0, &mut out_string);
835        out_string
836    }
837
838    pub fn save_binary<P: AsRef<Path>>(&self, path: P) -> VisitResult {
839        let mut writer = BufWriter::new(File::create(path)?);
840        writer.write_all(Self::MAGIC.as_bytes())?;
841        let mut stack = vec![self.root];
842        while let Some(node_handle) = stack.pop() {
843            let node = self.nodes.borrow(node_handle);
844            let name = node.name.as_bytes();
845            writer.write_u32::<LittleEndian>(name.len() as u32)?;
846            writer.write_all(name)?;
847
848            writer.write_u32::<LittleEndian>(node.fields.len() as u32)?;
849            for field in node.fields.iter() {
850                Field::save(field, &mut writer)?
851            }
852
853            writer.write_u32::<LittleEndian>(node.children.len() as u32)?;
854            stack.extend_from_slice(&node.children);
855        }
856        Ok(())
857    }
858
859    fn load_node_binary(&mut self, file: &mut dyn Read) -> Result<Handle<Node>, VisitError> {
860        let name_len = file.read_u32::<LittleEndian>()? as usize;
861        let mut raw_name = vec![Default::default(); name_len];
862        file.read_exact(raw_name.as_mut_slice())?;
863
864        let mut node = Node {
865            name: String::from_utf8(raw_name)?,
866            ..Node::default()
867        };
868
869        let field_count = file.read_u32::<LittleEndian>()? as usize;
870        for _ in 0..field_count {
871            let field = Field::load(file)?;
872            node.fields.push(field);
873        }
874
875        let mut children = Vec::new();
876        let child_count = file.read_u32::<LittleEndian>()? as usize;
877        for _ in 0..child_count {
878            children.push(self.load_node_binary(file)?);
879        }
880
881        node.children = children.clone();
882
883        let handle = self.nodes.spawn(node);
884        for child_handle in children.iter() {
885            let child = self.nodes.borrow_mut(*child_handle);
886            child.parent = handle;
887        }
888
889        Ok(handle)
890    }
891
892    pub async fn load_binary<P: AsRef<Path>>(path: P) -> Result<Self, VisitError> {
893        let mut reader = Cursor::new(io::load_file(path).await?);
894        let mut magic: [u8; 4] = Default::default();
895        reader.read_exact(&mut magic)?;
896        if !magic.eq(Self::MAGIC.as_bytes()) {
897            return Err(VisitError::NotSupportedFormat);
898        }
899        let mut visitor = Self {
900            nodes: Pool::new(),
901            rc_map: Default::default(),
902            arc_map: Default::default(),
903            reading: true,
904            current_node: Handle::NONE,
905            root: Handle::NONE,
906        };
907        visitor.root = visitor.load_node_binary(&mut reader)?;
908        visitor.current_node = visitor.root;
909        Ok(visitor)
910    }
911}
912
913impl<T> Visit for RefCell<T>
914where
915    T: Visit + 'static,
916{
917    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
918        if let Ok(mut data) = self.try_borrow_mut() {
919            data.visit(name, visitor)
920        } else {
921            Err(VisitError::RefCellAlreadyMutableBorrowed)
922        }
923    }
924}
925
926impl<T> Visit for Vec<T>
927where
928    T: Default + Visit + 'static,
929{
930    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
931        visitor.enter_region(name)?;
932
933        let mut len = self.len() as u32;
934        len.visit("Length", visitor)?;
935
936        if visitor.reading {
937            for index in 0..len {
938                let region_name = format!("Item{}", index);
939                visitor.enter_region(region_name.as_str())?;
940                let mut object = T::default();
941                object.visit("ItemData", visitor)?;
942                self.push(object);
943                visitor.leave_region()?;
944            }
945        } else {
946            for (index, item) in self.iter_mut().enumerate() {
947                let region_name = format!("Item{}", index);
948                visitor.enter_region(region_name.as_str())?;
949                item.visit("ItemData", visitor)?;
950                visitor.leave_region()?;
951            }
952        }
953        visitor.leave_region()?;
954        Ok(())
955    }
956}
957
958impl<T> Visit for Option<T>
959where
960    T: Default + Visit + 'static,
961{
962    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
963        visitor.enter_region(name)?;
964
965        let mut is_some = if self.is_some() { 1u8 } else { 0u8 };
966        is_some.visit("IsSome", visitor)?;
967
968        if is_some != 0 {
969            if visitor.reading {
970                let mut value = T::default();
971                value.visit("Data", visitor)?;
972                *self = Some(value);
973            } else {
974                self.as_mut().unwrap().visit("Data", visitor)?;
975            }
976        }
977
978        visitor.leave_region()?;
979        Ok(())
980    }
981}
982
983impl Visit for String {
984    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
985        visitor.enter_region(name)?;
986
987        let mut len = self.as_bytes().len() as u32;
988        len.visit("Length", visitor)?;
989
990        let mut data = if visitor.reading {
991            Vec::new()
992        } else {
993            Vec::from(self.as_bytes())
994        };
995
996        let mut proxy = Data { vec: &mut data };
997        proxy.visit("Data", visitor)?;
998
999        if visitor.reading {
1000            *self = String::from_utf8(data)?;
1001        }
1002        visitor.leave_region()
1003    }
1004}
1005
1006impl Visit for PathBuf {
1007    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1008        visitor.enter_region(name)?;
1009
1010        // We have to replace Windows back slashes \ to forward / to make paths portable
1011        // across all OSes.
1012        let portable_path = replace_slashes(&self);
1013
1014        let bytes = if let Some(path_str) = portable_path.as_os_str().to_str() {
1015            path_str.as_bytes()
1016        } else {
1017            return Err(VisitError::InvalidName);
1018        };
1019
1020        let mut len = bytes.len() as u32;
1021        len.visit("Length", visitor)?;
1022
1023        let mut data = if visitor.reading {
1024            Vec::new()
1025        } else {
1026            Vec::from(bytes)
1027        };
1028
1029        let mut proxy = Data { vec: &mut data };
1030        proxy.visit("Data", visitor)?;
1031
1032        if visitor.reading {
1033            *self = PathBuf::from(String::from_utf8(data)?);
1034        }
1035
1036        visitor.leave_region()
1037    }
1038}
1039
1040impl<T> Visit for Cell<T>
1041where
1042    T: Copy + Clone + Visit + 'static,
1043{
1044    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1045        let mut value = self.get();
1046        value.visit(name, visitor)?;
1047        if visitor.is_reading() {
1048            self.set(value);
1049        }
1050        Ok(())
1051    }
1052}
1053
1054impl<T> Visit for Rc<T>
1055where
1056    T: Visit + 'static,
1057{
1058    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1059        visitor.enter_region(name)?;
1060
1061        if visitor.reading {
1062            let mut raw = 0u64;
1063            raw.visit("Id", visitor)?;
1064            if raw == 0 {
1065                return Err(VisitError::UnexpectedRcNullIndex);
1066            }
1067            if let Some(ptr) = visitor.rc_map.get(&raw) {
1068                if let Ok(res) = Rc::downcast::<T>(ptr.clone()) {
1069                    *self = res;
1070                } else {
1071                    return Err(VisitError::TypeMismatch);
1072                }
1073            } else {
1074                // Remember that we already visited data Rc store.
1075                visitor.rc_map.insert(raw as u64, self.clone());
1076
1077                let raw = rc_to_raw(self);
1078                unsafe { &mut *raw }.visit("RcData", visitor)?;
1079            }
1080        } else {
1081            // Take raw pointer to inner data.
1082            let raw = rc_to_raw(self);
1083
1084            // Save it as id.
1085            let mut index = raw as u64;
1086            index.visit("Id", visitor)?;
1087
1088            if let Entry::Vacant(entry) = visitor.rc_map.entry(index) {
1089                entry.insert(self.clone());
1090                unsafe { &mut *raw }.visit("RcData", visitor)?;
1091            }
1092        }
1093
1094        visitor.leave_region()?;
1095
1096        Ok(())
1097    }
1098}
1099
1100impl<T> Visit for Mutex<T>
1101where
1102    T: Visit + Send,
1103{
1104    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1105        self.get_mut()?.visit(name, visitor)
1106    }
1107}
1108
1109impl<T> Visit for parking_lot::Mutex<T>
1110where
1111    T: Visit + Send,
1112{
1113    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1114        self.get_mut().visit(name, visitor)
1115    }
1116}
1117
1118impl<T> Visit for Box<T>
1119where
1120    T: Visit,
1121{
1122    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1123        self.deref_mut().visit(name, visitor)
1124    }
1125}
1126
1127impl<T> Visit for RwLock<T>
1128where
1129    T: Visit + Send,
1130{
1131    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1132        self.write()?.visit(name, visitor)
1133    }
1134}
1135
1136fn arc_to_raw<T>(arc: &Arc<T>) -> *mut T {
1137    &**arc as *const T as *mut T
1138}
1139
1140fn rc_to_raw<T>(rc: &Rc<T>) -> *mut T {
1141    &**rc as *const T as *mut T
1142}
1143
1144impl<T> Visit for Arc<T>
1145where
1146    T: Visit + Send + Sync + 'static,
1147{
1148    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1149        visitor.enter_region(name)?;
1150
1151        if visitor.reading {
1152            let mut raw = 0u64;
1153            raw.visit("Id", visitor)?;
1154            if raw == 0 {
1155                return Err(VisitError::UnexpectedRcNullIndex);
1156            }
1157            if let Some(ptr) = visitor.arc_map.get(&raw) {
1158                if let Ok(res) = Arc::downcast::<T>(ptr.clone()) {
1159                    *self = res;
1160                } else {
1161                    return Err(VisitError::TypeMismatch);
1162                }
1163            } else {
1164                // Remember that we already visited data Rc store.
1165                visitor.arc_map.insert(raw as u64, self.clone());
1166
1167                let raw = arc_to_raw(self);
1168                unsafe { &mut *raw }.visit("ArcData", visitor)?;
1169            }
1170        } else {
1171            // Take raw pointer to inner data.
1172            let raw = arc_to_raw(self);
1173
1174            // Save it as id.
1175            let mut index = raw as u64;
1176            index.visit("Id", visitor)?;
1177
1178            if let Entry::Vacant(entry) = visitor.arc_map.entry(index) {
1179                entry.insert(self.clone());
1180                unsafe { &mut *raw }.visit("ArcData", visitor)?;
1181            }
1182        }
1183
1184        visitor.leave_region()?;
1185
1186        Ok(())
1187    }
1188}
1189
1190impl<T> Visit for std::rc::Weak<T>
1191where
1192    T: Default + Visit + 'static,
1193{
1194    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1195        visitor.enter_region(name)?;
1196
1197        if visitor.reading {
1198            let mut raw = 0u64;
1199            raw.visit("Id", visitor)?;
1200
1201            if raw != 0 {
1202                if let Some(ptr) = visitor.rc_map.get(&raw) {
1203                    if let Ok(res) = Rc::downcast::<T>(ptr.clone()) {
1204                        *self = Rc::downgrade(&res);
1205                    } else {
1206                        return Err(VisitError::TypeMismatch);
1207                    }
1208                } else {
1209                    // Create new value wrapped into Rc and deserialize it.
1210                    let rc = Rc::new(T::default());
1211                    visitor.rc_map.insert(raw as u64, rc.clone());
1212
1213                    let raw = rc_to_raw(&rc);
1214                    unsafe { &mut *raw }.visit("RcData", visitor)?;
1215
1216                    *self = Rc::downgrade(&rc);
1217                }
1218            }
1219        } else if let Some(rc) = std::rc::Weak::upgrade(self) {
1220            // Take raw pointer to inner data.
1221            let raw = rc_to_raw(&rc);
1222
1223            // Save it as id.
1224            let mut index = raw as u64;
1225            index.visit("Id", visitor)?;
1226
1227            if let Entry::Vacant(entry) = visitor.rc_map.entry(index) {
1228                entry.insert(rc);
1229                unsafe { &mut *raw }.visit("RcData", visitor)?;
1230            }
1231        } else {
1232            let mut index = 0u64;
1233            index.visit("Id", visitor)?;
1234        }
1235
1236        visitor.leave_region()?;
1237
1238        Ok(())
1239    }
1240}
1241
1242impl<T> Visit for std::sync::Weak<T>
1243where
1244    T: Default + Visit + Send + Sync + 'static,
1245{
1246    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1247        visitor.enter_region(name)?;
1248
1249        if visitor.reading {
1250            let mut raw = 0u64;
1251            raw.visit("Id", visitor)?;
1252
1253            if raw != 0 {
1254                if let Some(ptr) = visitor.arc_map.get(&raw) {
1255                    if let Ok(res) = Arc::downcast::<T>(ptr.clone()) {
1256                        *self = Arc::downgrade(&res);
1257                    } else {
1258                        return Err(VisitError::TypeMismatch);
1259                    }
1260                } else {
1261                    // Create new value wrapped into Arc and deserialize it.
1262                    let arc = Arc::new(T::default());
1263                    visitor.arc_map.insert(raw as u64, arc.clone());
1264
1265                    let raw = arc_to_raw(&arc);
1266                    unsafe { &mut *raw }.visit("ArcData", visitor)?;
1267
1268                    *self = Arc::downgrade(&arc);
1269                }
1270            }
1271        } else if let Some(arc) = std::sync::Weak::upgrade(self) {
1272            // Take raw pointer to inner data.
1273            let raw = arc_to_raw(&arc);
1274
1275            // Save it as id.
1276            let mut index = raw as u64;
1277            index.visit("Id", visitor)?;
1278
1279            if let Entry::Vacant(entry) = visitor.arc_map.entry(index) {
1280                entry.insert(arc);
1281                unsafe { &mut *raw }.visit("ArcData", visitor)?;
1282            }
1283        } else {
1284            let mut index = 0u64;
1285            index.visit("Id", visitor)?;
1286        }
1287
1288        visitor.leave_region()?;
1289
1290        Ok(())
1291    }
1292}
1293
1294impl<K, V> Visit for FxHashMap<K, V>
1295where
1296    K: Visit + Default + Clone + Hash + Eq,
1297    V: Visit + Default,
1298{
1299    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1300        visitor.enter_region(name)?;
1301
1302        let mut count = self.len() as u32;
1303        count.visit("Count", visitor)?;
1304
1305        if visitor.is_reading() {
1306            for i in 0..(count as usize) {
1307                let name = format!("Item{}", i);
1308
1309                visitor.enter_region(name.as_str())?;
1310
1311                let mut key = K::default();
1312                key.visit("Key", visitor)?;
1313
1314                let mut value = V::default();
1315                value.visit("Value", visitor)?;
1316
1317                self.insert(key, value);
1318
1319                visitor.leave_region()?;
1320            }
1321        } else {
1322            for (i, (key, value)) in self.iter_mut().enumerate() {
1323                let name = format!("Item{}", i);
1324
1325                visitor.enter_region(name.as_str())?;
1326
1327                let mut key = key.clone();
1328                key.visit("Key", visitor)?;
1329
1330                value.visit("Value", visitor)?;
1331
1332                visitor.leave_region()?;
1333            }
1334        }
1335
1336        visitor.leave_region()
1337    }
1338}
1339
1340impl<K, V> Visit for HashMap<K, V>
1341where
1342    K: Visit + Default + Clone + Hash + Eq,
1343    V: Visit + Default,
1344{
1345    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1346        visitor.enter_region(name)?;
1347
1348        let mut count = self.len() as u32;
1349        count.visit("Count", visitor)?;
1350
1351        if visitor.is_reading() {
1352            for i in 0..(count as usize) {
1353                let name = format!("Item{}", i);
1354
1355                visitor.enter_region(name.as_str())?;
1356
1357                let mut key = K::default();
1358                key.visit("Key", visitor)?;
1359
1360                let mut value = V::default();
1361                value.visit("Value", visitor)?;
1362
1363                self.insert(key, value);
1364
1365                visitor.leave_region()?;
1366            }
1367        } else {
1368            for (i, (key, value)) in self.iter_mut().enumerate() {
1369                let name = format!("Item{}", i);
1370
1371                visitor.enter_region(name.as_str())?;
1372
1373                let mut key = key.clone();
1374                key.visit("Key", visitor)?;
1375
1376                value.visit("Value", visitor)?;
1377
1378                visitor.leave_region()?;
1379            }
1380        }
1381
1382        visitor.leave_region()
1383    }
1384}
1385
1386impl<T: Default + Visit, const SIZE: usize> Visit for [T; SIZE] {
1387    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1388        visitor.enter_region(name)?;
1389
1390        let mut len = SIZE as u32;
1391        len.visit("Length", visitor)?;
1392
1393        if visitor.reading {
1394            if len > SIZE as u32 {
1395                return VisitResult::Err(VisitError::User(format!(
1396                    "Not enough space in static array, got {}, needed {}!",
1397                    len, SIZE
1398                )));
1399            }
1400
1401            for index in 0..len {
1402                let region_name = format!("Item{}", index);
1403                visitor.enter_region(region_name.as_str())?;
1404                let mut object = T::default();
1405                object.visit("ItemData", visitor)?;
1406                self[index as usize] = object;
1407                visitor.leave_region()?;
1408            }
1409        } else {
1410            for (index, item) in self.iter_mut().enumerate() {
1411                let region_name = format!("Item{}", index);
1412                visitor.enter_region(region_name.as_str())?;
1413                item.visit("ItemData", visitor)?;
1414                visitor.leave_region()?;
1415            }
1416        }
1417
1418        visitor.leave_region()
1419    }
1420}
1421
1422impl<T: Visit> Visit for Range<T> {
1423    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1424        visitor.enter_region(name)?;
1425
1426        self.start.visit("Start", visitor)?;
1427        self.end.visit("End", visitor)?;
1428
1429        visitor.leave_region()
1430    }
1431}
1432
1433#[cfg(test)]
1434mod test {
1435    use crate::visitor::{Data, Visit, VisitError, VisitResult, Visitor};
1436    use std::{fs::File, io::Write, path::Path, rc::Rc};
1437
1438    pub struct Model {
1439        data: u64,
1440    }
1441
1442    pub struct Texture {
1443        data: Vec<u8>,
1444    }
1445
1446    impl Visit for Texture {
1447        fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1448            visitor.enter_region(name)?;
1449            let mut proxy = Data {
1450                vec: &mut self.data,
1451            };
1452            proxy.visit("Data", visitor)?;
1453            visitor.leave_region()
1454        }
1455    }
1456
1457    impl Visit for Model {
1458        fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1459            visitor.enter_region(name)?;
1460            self.data.visit("Data", visitor)?;
1461            visitor.leave_region()
1462        }
1463    }
1464
1465    impl Visit for ResourceKind {
1466        fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1467            match self {
1468                ResourceKind::Unknown => Err(VisitError::User("invalid resource type".to_string())),
1469                ResourceKind::Texture(tex) => tex.visit(name, visitor),
1470                ResourceKind::Model(model) => model.visit(name, visitor),
1471            }
1472        }
1473    }
1474
1475    #[allow(dead_code)]
1476    pub enum ResourceKind {
1477        Unknown,
1478        Model(Model),
1479        Texture(Texture),
1480    }
1481
1482    struct Resource {
1483        kind: ResourceKind,
1484        data: u16,
1485    }
1486
1487    impl Resource {
1488        fn new(kind: ResourceKind) -> Self {
1489            Self { kind, data: 0 }
1490        }
1491    }
1492
1493    impl Default for Resource {
1494        fn default() -> Self {
1495            Self {
1496                kind: ResourceKind::Unknown,
1497                data: 0,
1498            }
1499        }
1500    }
1501
1502    impl Visit for Resource {
1503        fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1504            visitor.enter_region(name)?;
1505            if visitor.reading {
1506            } else {
1507                let mut kind_id: u8 = match &self.kind {
1508                    ResourceKind::Unknown => {
1509                        return Err(VisitError::User("Invalid resource!".to_string()))
1510                    }
1511                    ResourceKind::Model(_) => 0,
1512                    ResourceKind::Texture(_) => 1,
1513                };
1514                kind_id.visit("KindId", visitor)?;
1515                self.kind.visit("KindData", visitor)?;
1516            }
1517            self.data.visit("ResData", visitor)?;
1518            visitor.leave_region()
1519        }
1520    }
1521
1522    #[derive(Default)]
1523    struct Foo {
1524        bar: u64,
1525        shared_resource: Option<Rc<Resource>>,
1526    }
1527
1528    impl Foo {
1529        fn new(resource: Rc<Resource>) -> Self {
1530            Self {
1531                bar: 123,
1532                shared_resource: Some(resource),
1533            }
1534        }
1535    }
1536
1537    impl Visit for Foo {
1538        fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
1539            visitor.enter_region(name)?;
1540            self.bar.visit("Bar", visitor)?;
1541            self.shared_resource.visit("SharedResource", visitor)?;
1542            visitor.leave_region()
1543        }
1544    }
1545
1546    #[test]
1547    fn visitor_test() {
1548        let path = Path::new("test.bin");
1549
1550        // Save
1551        {
1552            let mut visitor = Visitor::new();
1553            let mut resource = Rc::new(Resource::new(ResourceKind::Model(Model { data: 555 })));
1554            resource.visit("SharedResource", &mut visitor).unwrap();
1555
1556            let mut objects = vec![Foo::new(resource.clone()), Foo::new(resource)];
1557
1558            objects.visit("Objects", &mut visitor).unwrap();
1559
1560            visitor.save_binary(path).unwrap();
1561            if let Ok(mut file) = File::create(Path::new("test.txt")) {
1562                file.write_all(visitor.save_text().as_bytes()).unwrap();
1563            }
1564        }
1565
1566        // Load
1567        {
1568            let mut visitor = futures::executor::block_on(Visitor::load_binary(path)).unwrap();
1569            let mut resource: Rc<Resource> = Rc::new(Default::default());
1570            resource.visit("SharedResource", &mut visitor).unwrap();
1571
1572            let mut objects: Vec<Foo> = Vec::new();
1573            objects.visit("Objects", &mut visitor).unwrap();
1574        }
1575    }
1576}