Skip to main content

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::{
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)] // Fix your shit first before releasing.
246    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
247        let mut region = visitor.enter_region(name)?;
248
249        // We have to replace Windows back slashes \ to forward / to make paths portable
250        // across all OSes.
251        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                // Sometimes visiting is done experimentally, just to see if it would succeed, and visiting continues along a different
320                // path on failure. This means that the visitor must be in a valid state even after a failure, so we must remove
321                // the invalid rc_map entry if visiting failed.
322                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// FIXME: Visiting an Rc/Arc is undefined behavior because it mutates the shared data.
385#[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// FIXME: Visiting an Rc/Arc is undefined behavior because it mutates the shared data.
391#[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                // Sometimes visiting is done experimentally, just to see if it would succeed, and visiting continues along a different
423                // path on failure. This means that the visitor must be in a valid state even after a failure, so we must remove
424                // the invalid arc_map entry if visiting failed.
425                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                    // Create new value wrapped into Rc and deserialize it.
466                    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                    // Sometimes visiting is done experimentally, just to see if it would succeed, and visiting continues along a different
472                    // path on failure. This means that the visitor must be in a valid state even after a failure, so we must remove
473                    // the invalid rc_map entry if visiting failed.
474                    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                    // Sometimes visiting is done experimentally, just to see if it would succeed, and visiting continues along a different
525                    // path on failure. This means that the visitor must be in a valid state even after a failure, so we must remove
526                    // the invalid arc_map entry if visiting failed.
527                    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}