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