1use crate::visitor::VisitorVersion;
22use crate::{
23 replace_slashes,
24 visitor::{
25 error::VisitError, field::FieldKind, BinaryBlob, Field, Visit, VisitResult, Visitor,
26 },
27};
28use nalgebra::{Matrix2, Matrix3, Matrix4, UnitComplex, UnitQuaternion, Vector2, Vector3, Vector4};
29use std::{
30 any::Any,
31 cell::{Cell, RefCell},
32 collections::{HashMap, HashSet},
33 hash::{BuildHasher, Hash},
34 ops::{DerefMut, Range},
35 path::PathBuf,
36 rc::Rc,
37 sync::{Arc, Mutex, RwLock},
38 time::Duration,
39};
40use uuid::Uuid;
41
42macro_rules! impl_visit_as_field {
43 ($type_name:ty, $($kind:tt)*) => {
44 impl Visit for $type_name {
45 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
46 if visitor.reading {
47 if let Some(field) = visitor.find_field(name) {
48 match field.kind {
49 $($kind)*(data) => {
50 *self = data.clone();
51 Ok(())
52 },
53 _ => Err(VisitError::FieldTypeDoesNotMatch {
54 expected: stringify!($($kind)*),
55 actual: format!("{:?}", field.kind),
56 }),
57 }
58 } else {
59 Err(VisitError::field_does_not_exist(name, visitor))
60 }
61 } else if visitor.find_field(name).is_some() {
62 Err(VisitError::FieldAlreadyExists(name.to_owned()))
63 } else {
64 let node = visitor.current_node();
65 node.fields.push(Field::new(name, $($kind)*(self.clone())));
66 Ok(())
67 }
68 }
69 }
70 };
71}
72
73impl_visit_as_field!(u64, FieldKind::U64);
74impl_visit_as_field!(i64, FieldKind::I64);
75impl_visit_as_field!(u32, FieldKind::U32);
76impl_visit_as_field!(i32, FieldKind::I32);
77impl_visit_as_field!(u16, FieldKind::U16);
78impl_visit_as_field!(i16, FieldKind::I16);
79impl_visit_as_field!(u8, FieldKind::U8);
80impl_visit_as_field!(i8, FieldKind::I8);
81impl_visit_as_field!(f32, FieldKind::F32);
82impl_visit_as_field!(f64, FieldKind::F64);
83impl_visit_as_field!(UnitQuaternion<f32>, FieldKind::UnitQuaternion);
84impl_visit_as_field!(Matrix4<f32>, FieldKind::Matrix4);
85impl_visit_as_field!(bool, FieldKind::Bool);
86impl_visit_as_field!(Matrix3<f32>, FieldKind::Matrix3);
87impl_visit_as_field!(Uuid, FieldKind::Uuid);
88impl_visit_as_field!(UnitComplex<f32>, FieldKind::UnitComplex);
89impl_visit_as_field!(Matrix2<f32>, FieldKind::Matrix2);
90
91impl_visit_as_field!(Vector2<f32>, FieldKind::Vector2F32);
92impl_visit_as_field!(Vector3<f32>, FieldKind::Vector3F32);
93impl_visit_as_field!(Vector4<f32>, FieldKind::Vector4F32);
94
95impl_visit_as_field!(Vector2<f64>, FieldKind::Vector2F64);
96impl_visit_as_field!(Vector3<f64>, FieldKind::Vector3F64);
97impl_visit_as_field!(Vector4<f64>, FieldKind::Vector4F64);
98
99impl_visit_as_field!(Vector2<i8>, FieldKind::Vector2I8);
100impl_visit_as_field!(Vector3<i8>, FieldKind::Vector3I8);
101impl_visit_as_field!(Vector4<i8>, FieldKind::Vector4I8);
102
103impl_visit_as_field!(Vector2<u8>, FieldKind::Vector2U8);
104impl_visit_as_field!(Vector3<u8>, FieldKind::Vector3U8);
105impl_visit_as_field!(Vector4<u8>, FieldKind::Vector4U8);
106
107impl_visit_as_field!(Vector2<i16>, FieldKind::Vector2I16);
108impl_visit_as_field!(Vector3<i16>, FieldKind::Vector3I16);
109impl_visit_as_field!(Vector4<i16>, FieldKind::Vector4I16);
110
111impl_visit_as_field!(Vector2<u16>, FieldKind::Vector2U16);
112impl_visit_as_field!(Vector3<u16>, FieldKind::Vector3U16);
113impl_visit_as_field!(Vector4<u16>, FieldKind::Vector4U16);
114
115impl_visit_as_field!(Vector2<i32>, FieldKind::Vector2I32);
116impl_visit_as_field!(Vector3<i32>, FieldKind::Vector3I32);
117impl_visit_as_field!(Vector4<i32>, FieldKind::Vector4I32);
118
119impl_visit_as_field!(Vector2<u32>, FieldKind::Vector2U32);
120impl_visit_as_field!(Vector3<u32>, FieldKind::Vector3U32);
121impl_visit_as_field!(Vector4<u32>, FieldKind::Vector4U32);
122
123impl_visit_as_field!(Vector2<i64>, FieldKind::Vector2I64);
124impl_visit_as_field!(Vector3<i64>, FieldKind::Vector3I64);
125impl_visit_as_field!(Vector4<i64>, FieldKind::Vector4I64);
126
127impl_visit_as_field!(Vector2<u64>, FieldKind::Vector2U64);
128impl_visit_as_field!(Vector3<u64>, FieldKind::Vector3U64);
129impl_visit_as_field!(Vector4<u64>, FieldKind::Vector4U64);
130
131impl<T> Visit for RefCell<T>
132where
133 T: Visit + 'static,
134{
135 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
136 if let Ok(mut data) = self.try_borrow_mut() {
137 data.visit(name, visitor)
138 } else {
139 Err(VisitError::RefCellAlreadyMutableBorrowed)
140 }
141 }
142}
143
144impl<T> Visit for Vec<T>
145where
146 T: Default + Visit + 'static,
147{
148 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
149 let mut region = visitor.enter_region(name)?;
150
151 let mut len = self.len() as u32;
152 len.visit("Length", &mut region)?;
153
154 fn make_name(i: usize) -> String {
155 format!("Item{i}")
156 }
157
158 if region.reading {
159 self.clear();
160 for index in 0..len as usize {
161 if region.version == VisitorVersion::Legacy as u32 {
163 if let Ok(mut item_region) = region.enter_region(&make_name(index)) {
164 let mut object = T::default();
165 object.visit("ItemData", &mut item_region)?;
166 self.push(object);
167 continue;
168 }
169 } else {
170 let mut object = T::default();
172 object.visit(&make_name(index), &mut region)?;
173 self.push(object);
174 }
175 }
176 } else {
177 for (index, item) in self.iter_mut().enumerate() {
178 item.visit(&make_name(index), &mut region)?;
179 }
180 }
181
182 Ok(())
183 }
184}
185
186impl<T> Visit for Option<T>
187where
188 T: Default + Visit + 'static,
189{
190 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
191 let mut region = visitor.enter_region(name)?;
192
193 let mut is_some = u8::from(self.is_some());
194 is_some.visit("IsSome", &mut region)?;
195
196 if is_some != 0 {
197 if region.reading {
198 let mut value = T::default();
199 value.visit("Data", &mut region)?;
200 *self = Some(value);
201 } else {
202 self.as_mut().unwrap().visit("Data", &mut region)?;
203 }
204 } else if region.reading {
205 *self = None;
206 }
207
208 Ok(())
209 }
210}
211
212fn read_old_string_format(name: &str, visitor: &mut Visitor) -> Result<String, VisitError> {
213 let mut region = visitor.enter_region(name)?;
214
215 let mut len = 0u32;
216 len.visit("Length", &mut region)?;
217
218 let mut data = Vec::new();
219 let mut proxy = BinaryBlob { vec: &mut data };
220 proxy.visit("Data", &mut region)?;
221
222 Ok(String::from_utf8(data)?)
223}
224
225impl Visit for String {
226 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
227 if visitor.reading {
228 if let Ok(old_string) = read_old_string_format(name, visitor) {
229 *self = old_string;
230 Ok(())
231 } else if let Some(field) = visitor.find_field(name) {
232 match field.kind {
233 FieldKind::String(ref string) => {
234 *self = string.clone();
235 Ok(())
236 }
237 _ => Err(VisitError::FieldTypeDoesNotMatch {
238 expected: stringify!(FieldKind::String),
239 actual: format!("{:?}", field.kind),
240 }),
241 }
242 } else {
243 Err(VisitError::field_does_not_exist(name, visitor))
244 }
245 } else if visitor.find_field(name).is_some() {
246 Err(VisitError::FieldAlreadyExists(name.to_owned()))
247 } else {
248 let node = visitor.current_node();
249 node.fields
250 .push(Field::new(name, FieldKind::String(self.clone())));
251 Ok(())
252 }
253 }
254}
255
256impl Visit for PathBuf {
257 #[allow(clippy::needless_borrows_for_generic_args)] fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
259 let mut region = visitor.enter_region(name)?;
260
261 let portable_path = replace_slashes(&self);
264
265 let bytes = if let Some(path_str) = portable_path.as_os_str().to_str() {
266 path_str.as_bytes()
267 } else {
268 return Err(VisitError::InvalidName);
269 };
270
271 let mut len = bytes.len() as u32;
272 len.visit("Length", &mut region)?;
273
274 let mut data = if region.reading {
275 Vec::new()
276 } else {
277 Vec::from(bytes)
278 };
279
280 let mut proxy = BinaryBlob { vec: &mut data };
281 proxy.visit("Data", &mut region)?;
282
283 if region.reading {
284 *self = PathBuf::from(String::from_utf8(data)?);
285 }
286
287 Ok(())
288 }
289}
290
291impl<T> Visit for Cell<T>
292where
293 T: Copy + Clone + Visit + 'static,
294{
295 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
296 let mut value = self.get();
297 value.visit(name, visitor)?;
298 if visitor.is_reading() {
299 self.set(value);
300 }
301 Ok(())
302 }
303}
304
305impl<T> Visit for Rc<T>
306where
307 T: Visit + 'static,
308{
309 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
310 let mut region = visitor.enter_region(name)?;
311
312 if region.reading {
313 let mut id = 0u64;
314 id.visit("Id", &mut region)?;
315 if id == 0 {
316 return Err(VisitError::UnexpectedRcNullIndex);
317 }
318 if let Some(ptr) = region.rc_map.get(&id) {
319 if let Ok(res) = Rc::downcast::<T>(ptr.clone()) {
320 *self = res;
321 } else {
322 return Err(VisitError::TypeMismatch {
323 expected: std::any::type_name::<T>(),
324 actual: region.type_name_map.get(&id).unwrap_or(&"MISSING"),
325 });
326 }
327 } else {
328 region.type_name_map.insert(id, std::any::type_name::<T>());
329 region.rc_map.insert(id, self.clone());
330 let result = unsafe { rc_to_raw(self).visit("RcData", &mut region) };
331 if result.is_err() {
335 region.type_name_map.remove(&id);
336 region.rc_map.remove(&id);
337 return result;
338 }
339 }
340 } else {
341 let (mut id, serialize_data) = region.rc_id(self);
342 id.visit("Id", &mut region)?;
343 if serialize_data {
344 unsafe { rc_to_raw(self).visit("RcData", &mut region)? };
345 }
346 }
347
348 Ok(())
349 }
350}
351
352impl<T> Visit for Mutex<T>
353where
354 T: Visit + Send,
355{
356 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
357 self.get_mut()?.visit(name, visitor)
358 }
359}
360
361impl<T> Visit for parking_lot::Mutex<T>
362where
363 T: Visit + Send,
364{
365 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
366 self.get_mut().visit(name, visitor)
367 }
368}
369
370impl<T> Visit for Box<T>
371where
372 T: Visit,
373{
374 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
375 self.deref_mut().visit(name, visitor)
376 }
377}
378
379impl<T> Visit for RwLock<T>
380where
381 T: Visit + Send,
382{
383 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
384 self.write()?.visit(name, visitor)
385 }
386}
387
388unsafe fn arc_to_ptr<T>(arc: &Arc<T>) -> *mut T {
389 &**arc as *const T as *mut T
390}
391
392unsafe fn rc_to_ptr<T>(rc: &Rc<T>) -> *mut T {
393 &**rc as *const T as *mut T
394}
395
396#[allow(clippy::mut_from_ref)]
398unsafe fn arc_to_raw<T>(arc: &Arc<T>) -> &mut T {
399 &mut *arc_to_ptr(arc)
400}
401
402#[allow(clippy::mut_from_ref)]
404unsafe fn rc_to_raw<T>(rc: &Rc<T>) -> &mut T {
405 &mut *rc_to_ptr(rc)
406}
407
408impl<T> Visit for Arc<T>
409where
410 T: Visit + Send + Sync + Any,
411{
412 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
413 let mut region = visitor.enter_region(name)?;
414
415 if region.reading {
416 let mut id = 0u64;
417 id.visit("Id", &mut region)?;
418 if id == 0 {
419 return Err(VisitError::UnexpectedRcNullIndex);
420 }
421 if let Some(ptr) = &mut region.arc_map.get(&id) {
422 if let Ok(res) = Arc::downcast::<T>(ptr.clone()) {
423 *self = res;
424 } else {
425 return Err(VisitError::TypeMismatch {
426 expected: std::any::type_name::<T>(),
427 actual: region.type_name_map.get(&id).unwrap_or(&"MISSING"),
428 });
429 }
430 } else {
431 region.type_name_map.insert(id, std::any::type_name::<T>());
432 region.arc_map.insert(id, self.clone());
433 let result = unsafe { arc_to_raw(self).visit("ArcData", &mut region) };
434 if result.is_err() {
438 region.type_name_map.remove(&id);
439 region.arc_map.remove(&id);
440 return result;
441 }
442 }
443 } else {
444 let (mut id, serialize_data) = region.arc_id(self);
445 id.visit("Id", &mut region)?;
446 if serialize_data {
447 unsafe { arc_to_raw(self).visit("ArcData", &mut region)? };
448 }
449 }
450
451 Ok(())
452 }
453}
454
455impl<T> Visit for std::rc::Weak<T>
456where
457 T: Default + Visit + Any,
458{
459 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
460 let mut region = visitor.enter_region(name)?;
461
462 if region.reading {
463 let mut id = 0u64;
464 id.visit("Id", &mut region)?;
465
466 if id != 0 {
467 if let Some(ptr) = &mut region.rc_map.get(&id) {
468 if let Ok(res) = Rc::downcast::<T>(ptr.clone()) {
469 *self = Rc::downgrade(&res);
470 } else {
471 return Err(VisitError::TypeMismatch {
472 expected: std::any::type_name::<T>(),
473 actual: region.type_name_map.get(&id).unwrap_or(&"MISSING"),
474 });
475 }
476 } else {
477 let rc = Rc::new(T::default());
479 region.type_name_map.insert(id, std::any::type_name::<T>());
480 region.rc_map.insert(id, rc.clone());
481
482 let result = unsafe { rc_to_raw(&rc).visit("RcData", &mut region) };
483 if result.is_err() {
487 region.type_name_map.remove(&id);
488 region.rc_map.remove(&id);
489 return result;
490 }
491
492 *self = Rc::downgrade(&rc);
493 }
494 }
495 } else if let Some(rc) = std::rc::Weak::upgrade(self) {
496 let (mut id, serialize_data) = region.rc_id(&rc);
497 id.visit("Id", &mut region)?;
498 if serialize_data {
499 unsafe { rc_to_raw(&rc).visit("RcData", &mut region)? };
500 }
501 } else {
502 let mut index = 0u64;
503 index.visit("Id", &mut region)?;
504 }
505
506 Ok(())
507 }
508}
509
510impl<T> Visit for std::sync::Weak<T>
511where
512 T: Default + Visit + Send + Sync + 'static,
513{
514 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
515 let mut region = visitor.enter_region(name)?;
516
517 if region.reading {
518 let mut id = 0u64;
519 id.visit("Id", &mut region)?;
520
521 if id != 0 {
522 if let Some(ptr) = region.arc_map.get(&id) {
523 if let Ok(res) = Arc::downcast::<T>(ptr.clone()) {
524 *self = Arc::downgrade(&res);
525 } else {
526 return Err(VisitError::TypeMismatch {
527 expected: std::any::type_name::<T>(),
528 actual: region.type_name_map.get(&id).unwrap_or(&"MISSING"),
529 });
530 }
531 } else {
532 let arc = Arc::new(T::default());
533 region.type_name_map.insert(id, std::any::type_name::<T>());
534 region.arc_map.insert(id, arc.clone());
535 let result = unsafe { arc_to_raw(&arc).visit("ArcData", &mut region) };
536 if result.is_err() {
540 region.type_name_map.remove(&id);
541 region.arc_map.remove(&id);
542 return result;
543 }
544 *self = Arc::downgrade(&arc);
545 }
546 }
547 } else if let Some(arc) = std::sync::Weak::upgrade(self) {
548 let (mut id, serialize_data) = region.arc_id(&arc);
549 id.visit("Id", &mut region)?;
550 if serialize_data {
551 unsafe { arc_to_raw(&arc) }.visit("ArcData", &mut region)?;
552 }
553 } else {
554 let mut index = 0u64;
555 index.visit("Id", &mut region)?;
556 }
557
558 Ok(())
559 }
560}
561
562impl<K, V, S> Visit for HashMap<K, V, S>
563where
564 K: Visit + Default + Clone + Hash + Eq,
565 V: Visit + Default,
566 S: BuildHasher + Clone,
567{
568 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
569 let mut region = visitor.enter_region(name)?;
570
571 let mut count = self.len() as u32;
572 count.visit("Count", &mut region)?;
573
574 if region.is_reading() {
575 self.clear();
576 for i in 0..(count as usize) {
577 let name = format!("Item{i}");
578
579 let mut region = region.enter_region(name.as_str())?;
580
581 let mut key = K::default();
582 key.visit("Key", &mut region)?;
583
584 let mut value = V::default();
585 value.visit("Value", &mut region)?;
586
587 self.insert(key, value);
588 }
589 } else {
590 for (i, (key, value)) in self.iter_mut().enumerate() {
591 let name = format!("Item{i}");
592
593 let mut region = region.enter_region(name.as_str())?;
594
595 let mut key = key.clone();
596 key.visit("Key", &mut region)?;
597
598 value.visit("Value", &mut region)?;
599 }
600 }
601
602 Ok(())
603 }
604}
605
606impl<K, S> Visit for HashSet<K, S>
607where
608 K: Visit + Default + Clone + Hash + Eq,
609 S: BuildHasher + Clone,
610{
611 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
612 let mut region = visitor.enter_region(name)?;
613
614 let mut count = self.len() as u32;
615 count.visit("Count", &mut region)?;
616
617 if region.is_reading() {
618 self.clear();
619 for i in 0..(count as usize) {
620 let name = format!("Item{i}");
621
622 let mut region = region.enter_region(name.as_str())?;
623
624 let mut key = K::default();
625 key.visit("Key", &mut region)?;
626
627 self.insert(key);
628 }
629 } else {
630 for (i, mut key) in self.clone().into_iter().enumerate() {
631 let name = format!("Item{i}");
632
633 let mut region = region.enter_region(name.as_str())?;
634
635 key.visit("Key", &mut region)?;
636 }
637 }
638
639 Ok(())
640 }
641}
642
643impl<T: Default + Visit, const SIZE: usize> Visit for [T; SIZE] {
644 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
645 let mut region = visitor.enter_region(name)?;
646
647 let mut len = SIZE as u32;
648 len.visit("Length", &mut region)?;
649
650 if region.reading {
651 if len > SIZE as u32 {
652 return VisitResult::Err(VisitError::User(format!(
653 "Not enough space in static array, got {len}, needed {SIZE}!"
654 )));
655 }
656
657 for index in 0..len {
658 let region_name = format!("Item{index}");
659 let mut region = region.enter_region(region_name.as_str())?;
660 let mut object = T::default();
661 object.visit("ItemData", &mut region)?;
662 self[index as usize] = object;
663 }
664 } else {
665 for (index, item) in self.iter_mut().enumerate() {
666 let region_name = format!("Item{index}");
667 let mut region = region.enter_region(region_name.as_str())?;
668 item.visit("ItemData", &mut region)?;
669 }
670 }
671
672 Ok(())
673 }
674}
675
676impl Visit for Duration {
677 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
678 let mut region = visitor.enter_region(name)?;
679
680 let mut secs: u64 = self.as_secs();
681 let mut nanos: u32 = self.subsec_nanos();
682
683 secs.visit("Secs", &mut region)?;
684 nanos.visit("Nanos", &mut region)?;
685
686 if region.is_reading() {
687 *self = Duration::new(secs, nanos);
688 }
689
690 Ok(())
691 }
692}
693
694impl Visit for char {
695 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
696 let mut bytes = *self as u32;
697 bytes.visit(name, visitor)?;
698 if visitor.is_reading() {
699 *self = char::from_u32(bytes).unwrap();
700 }
701 Ok(())
702 }
703}
704
705impl<T: Visit> Visit for Range<T> {
706 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
707 let mut region = visitor.enter_region(name)?;
708
709 self.start.visit("Start", &mut region)?;
710 self.end.visit("End", &mut region)?;
711
712 Ok(())
713 }
714}
715
716impl Visit for usize {
717 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
718 let mut this = *self as u64;
719 this.visit(name, visitor)?;
720 if visitor.is_reading() {
721 *self = this as usize;
722 }
723 Ok(())
724 }
725}
726
727impl Visit for isize {
728 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
729 let mut this = *self as i64;
730 this.visit(name, visitor)?;
731 if visitor.is_reading() {
732 *self = this as isize;
733 }
734 Ok(())
735 }
736}