1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use crate::io::{DecodeError, PathItem};
use std::convert::Infallible;
use thiserror::Error;
pub use wasmbin_derive::Visit;
#[derive(Error, Debug)]
pub enum VisitError<E> {
#[error(transparent)]
LazyDecode(DecodeError),
#[error(transparent)]
Custom(E),
}
impl<E> VisitError<E> {
pub(crate) fn in_path(self, item: PathItem) -> Self {
#[allow(clippy::match_wildcard_for_single_variants)]
match self {
VisitError::LazyDecode(err) => VisitError::LazyDecode(err.in_path(item)),
err => err,
}
}
}
impl From<VisitError<Infallible>> for DecodeError {
fn from(err: VisitError<Infallible>) -> Self {
match err {
VisitError::Custom(err) => match err {},
VisitError::LazyDecode(err) => err,
}
}
}
pub trait VisitResult {
type Error;
fn into_result(self) -> Result<(), Self::Error>;
}
impl VisitResult for () {
type Error = Infallible;
fn into_result(self) -> Result<(), Self::Error> {
Ok(())
}
}
impl VisitResult for bool {
type Error = ();
fn into_result(self) -> Result<(), Self::Error> {
match self {
true => Ok(()),
false => Err(()),
}
}
}
impl<E> VisitResult for Result<(), E> {
type Error = E;
fn into_result(self) -> Result<(), Self::Error> {
self
}
}
pub trait Visit: 'static + Sized {
fn visit<'a, T: 'static, R: VisitResult, F: FnMut(&'a T) -> R>(
&'a self,
mut f: F,
) -> Result<(), VisitError<R::Error>> {
self.visit_child(&mut move |item| f(item).into_result())
}
fn visit_mut<T: 'static, R: VisitResult, F: FnMut(&mut T) -> R>(
&mut self,
mut f: F,
) -> Result<(), VisitError<R::Error>> {
self.visit_child_mut(&mut move |item| f(item).into_result())
}
fn visit_child<'a, T: 'static, E, F: FnMut(&'a T) -> Result<(), E>>(
&'a self,
f: &mut F,
) -> Result<(), VisitError<E>> {
if let Some(v) = <dyn std::any::Any>::downcast_ref(self) {
f(v).map_err(VisitError::Custom)?;
}
self.visit_children(f)
}
fn visit_child_mut<T: 'static, E, F: FnMut(&mut T) -> Result<(), E>>(
&mut self,
f: &mut F,
) -> Result<(), VisitError<E>> {
if let Some(v) = <dyn std::any::Any>::downcast_mut(self) {
f(v).map_err(VisitError::Custom)?;
}
self.visit_children_mut(f)
}
fn visit_children<'a, T: 'static, E, F: FnMut(&'a T) -> Result<(), E>>(
&'a self,
_f: &mut F,
) -> Result<(), VisitError<E>> {
Ok(())
}
fn visit_children_mut<T: 'static, E, F: FnMut(&mut T) -> Result<(), E>>(
&mut self,
_f: &mut F,
) -> Result<(), VisitError<E>> {
Ok(())
}
}