fyrox_core/visitor/
impls.rs

1// Copyright (c) 2019-present Dmitry Stepanov and Fyrox Engine contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in all
11// copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19// SOFTWARE.
20
21use 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                // Backward compatibility with the previous version (verbose, non-flat).
162                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                    // Try to read the new (flattened) version.
171                    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)] // Fix your shit first before releasing.
258    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
259        let mut region = visitor.enter_region(name)?;
260
261        // We have to replace Windows back slashes \ to forward / to make paths portable
262        // across all OSes.
263        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                // Sometimes visiting is done experimentally, just to see if it would succeed, and visiting continues along a different
332                // path on failure. This means that the visitor must be in a valid state even after a failure, so we must remove
333                // the invalid rc_map entry if visiting failed.
334                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// FIXME: Visiting an Rc/Arc is undefined behavior because it mutates the shared data.
397#[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// FIXME: Visiting an Rc/Arc is undefined behavior because it mutates the shared data.
403#[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                // Sometimes visiting is done experimentally, just to see if it would succeed, and visiting continues along a different
435                // path on failure. This means that the visitor must be in a valid state even after a failure, so we must remove
436                // the invalid arc_map entry if visiting failed.
437                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                    // Create new value wrapped into Rc and deserialize it.
478                    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                    // Sometimes visiting is done experimentally, just to see if it would succeed, and visiting continues along a different
484                    // path on failure. This means that the visitor must be in a valid state even after a failure, so we must remove
485                    // the invalid rc_map entry if visiting failed.
486                    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                    // Sometimes visiting is done experimentally, just to see if it would succeed, and visiting continues along a different
537                    // path on failure. This means that the visitor must be in a valid state even after a failure, so we must remove
538                    // the invalid arc_map entry if visiting failed.
539                    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}