1use crate::prelude::*;
17
18use super::error::TraceDecodingError;
19use super::path::Path;
20use crate::{Composite, Primitive, Value, ValueDef, Variant};
21use core::marker::PhantomData;
22use scale_decode::visitor::TypeIdFor;
23use scale_type_resolver::TypeResolver;
24
25pub struct TraceDecodingVisitor<Resolver> {
28 path: Path,
29 marker: PhantomData<Resolver>,
30}
31
32impl<Resolver> TraceDecodingVisitor<Resolver> {
33 fn at_path(&self, path: Path) -> Self {
34 TraceDecodingVisitor { path, marker: PhantomData }
35 }
36 fn at_idx(&self, idx: usize) -> Self {
37 self.at_path(self.path.at_idx(idx))
38 }
39 fn at_field(&self, field: String) -> Self {
40 self.at_path(self.path.at_field(field))
41 }
42}
43
44impl<Resolver> Default for TraceDecodingVisitor<Resolver> {
45 fn default() -> Self {
46 Self::new()
47 }
48}
49
50impl<Resolver> TraceDecodingVisitor<Resolver> {
51 pub fn new() -> Self {
53 TraceDecodingVisitor { path: Path::new(), marker: PhantomData }
54 }
55}
56
57macro_rules! to_unnamed_composite {
58 ($self:ident, $value:ident) => {{
59 let mut f = move || {
60 let mut idx = 0;
61 let mut vals = Vec::with_capacity($value.remaining());
62
63 while let Some(val) = $value.decode_item($self.at_idx(idx)) {
64 match val {
65 Err(e) => {
66 let merged_error = e.with_outer_context(
67 || $self.path.at_idx(idx),
68 || Composite::Unnamed(vals.clone()),
69 |inner_value| {
70 let mut vals = vals.clone();
71 vals.push(inner_value);
72 Composite::Unnamed(vals)
73 },
74 );
75 return Err(merged_error);
76 }
77 Ok(v) => {
78 vals.push(v);
79 }
80 }
81
82 idx += 1;
83 }
84
85 Ok::<_, TraceDecodingError<_>>(Composite::Unnamed(vals))
86 };
87
88 f()
89 }};
90}
91
92macro_rules! to_unnamed_composite_value {
93 ($self:ident, $value:ident, $type_id:ident) => {{
94 let composite = to_unnamed_composite!($self, $value).map_err(|e| {
95 e.map_decoded_so_far(|c| Value {
96 value: ValueDef::Composite(c),
97 context: $type_id.clone(),
98 })
99 })?;
100
101 Ok(Value { value: ValueDef::Composite(composite), context: $type_id })
102 }};
103}
104
105impl<Resolver> scale_decode::Visitor for TraceDecodingVisitor<Resolver>
106where
107 Resolver: TypeResolver,
108{
109 type Value<'scale, 'resolver> = Value<TypeIdFor<Self>>;
110 type Error = TraceDecodingError<Value<TypeIdFor<Self>>>;
111 type TypeResolver = Resolver;
112
113 fn visit_bool<'scale, 'resolver>(
114 self,
115 value: bool,
116 type_id: TypeIdFor<Self>,
117 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
118 Ok(Value::with_context(ValueDef::Primitive(Primitive::Bool(value)), type_id))
119 }
120
121 fn visit_char<'scale, 'resolver>(
122 self,
123 value: char,
124 type_id: TypeIdFor<Self>,
125 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
126 Ok(Value::with_context(ValueDef::Primitive(Primitive::Char(value)), type_id))
127 }
128
129 fn visit_u8<'scale, 'resolver>(
130 self,
131 value: u8,
132 type_id: TypeIdFor<Self>,
133 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
134 self.visit_u128(value as u128, type_id)
135 }
136
137 fn visit_u16<'scale, 'resolver>(
138 self,
139 value: u16,
140 type_id: TypeIdFor<Self>,
141 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
142 self.visit_u128(value as u128, type_id)
143 }
144
145 fn visit_u32<'scale, 'resolver>(
146 self,
147 value: u32,
148 type_id: TypeIdFor<Self>,
149 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
150 self.visit_u128(value as u128, type_id)
151 }
152
153 fn visit_u64<'scale, 'resolver>(
154 self,
155 value: u64,
156 type_id: TypeIdFor<Self>,
157 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
158 self.visit_u128(value as u128, type_id)
159 }
160
161 fn visit_u128<'scale, 'resolver>(
162 self,
163 value: u128,
164 type_id: TypeIdFor<Self>,
165 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
166 Ok(Value::with_context(ValueDef::Primitive(Primitive::U128(value)), type_id))
167 }
168
169 fn visit_u256<'info>(
170 self,
171 value: &[u8; 32],
172 type_id: TypeIdFor<Self>,
173 ) -> Result<Self::Value<'_, 'info>, Self::Error> {
174 Ok(Value::with_context(ValueDef::Primitive(Primitive::U256(*value)), type_id))
175 }
176
177 fn visit_i8<'scale, 'resolver>(
178 self,
179 value: i8,
180 type_id: TypeIdFor<Self>,
181 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
182 self.visit_i128(value as i128, type_id)
183 }
184
185 fn visit_i16<'scale, 'resolver>(
186 self,
187 value: i16,
188 type_id: TypeIdFor<Self>,
189 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
190 self.visit_i128(value as i128, type_id)
191 }
192
193 fn visit_i32<'scale, 'resolver>(
194 self,
195 value: i32,
196 type_id: TypeIdFor<Self>,
197 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
198 self.visit_i128(value as i128, type_id)
199 }
200
201 fn visit_i64<'scale, 'resolver>(
202 self,
203 value: i64,
204 type_id: TypeIdFor<Self>,
205 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
206 self.visit_i128(value as i128, type_id)
207 }
208
209 fn visit_i128<'scale, 'resolver>(
210 self,
211 value: i128,
212 type_id: TypeIdFor<Self>,
213 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
214 Ok(Value::with_context(ValueDef::Primitive(Primitive::I128(value)), type_id))
215 }
216
217 fn visit_i256<'info>(
218 self,
219 value: &[u8; 32],
220 type_id: TypeIdFor<Self>,
221 ) -> Result<Self::Value<'_, 'info>, Self::Error> {
222 Ok(Value::with_context(ValueDef::Primitive(Primitive::I256(*value)), type_id))
223 }
224
225 fn visit_bitsequence<'scale, 'info>(
226 self,
227 value: &mut scale_decode::visitor::types::BitSequence<'scale>,
228 type_id: TypeIdFor<Self>,
229 ) -> Result<Self::Value<'scale, 'info>, Self::Error> {
230 let bits: Result<_, _> = value.decode()?.collect();
231 Ok(Value::with_context(ValueDef::BitSequence(bits?), type_id))
232 }
233
234 fn visit_str<'scale, 'info>(
235 self,
236 value: &mut scale_decode::visitor::types::Str<'scale>,
237 type_id: TypeIdFor<Self>,
238 ) -> Result<Self::Value<'scale, 'info>, Self::Error> {
239 Ok(Value::with_context(
240 ValueDef::Primitive(Primitive::String(value.as_str()?.to_owned())),
241 type_id,
242 ))
243 }
244
245 fn visit_sequence<'scale, 'resolver>(
246 self,
247 value: &mut scale_decode::visitor::types::Sequence<'scale, 'resolver, Self::TypeResolver>,
248 type_id: TypeIdFor<Self>,
249 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
250 to_unnamed_composite_value!(self, value, type_id)
251 }
252
253 fn visit_array<'scale, 'resolver>(
254 self,
255 value: &mut scale_decode::visitor::types::Array<'scale, 'resolver, Self::TypeResolver>,
256 type_id: scale_decode::visitor::TypeIdFor<Self>,
257 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
258 to_unnamed_composite_value!(self, value, type_id)
259 }
260
261 fn visit_tuple<'scale, 'resolver>(
262 self,
263 value: &mut scale_decode::visitor::types::Tuple<'scale, 'resolver, Self::TypeResolver>,
264 type_id: TypeIdFor<Self>,
265 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
266 to_unnamed_composite_value!(self, value, type_id)
267 }
268
269 fn visit_variant<'scale, 'resolver>(
270 self,
271 value: &mut scale_decode::visitor::types::Variant<'scale, 'resolver, Self::TypeResolver>,
272 type_id: TypeIdFor<Self>,
273 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
274 let variant_name = value.name();
275 let path = self.path.at_variant(variant_name.to_owned());
276 let values = visit_composite(&self, value.fields());
277 match values {
278 Err(e) => {
279 let merged_error = e.with_outer_context(
280 || path.clone(),
281 || Value {
282 value: ValueDef::Variant(Variant {
283 name: variant_name.to_owned(),
284 values: Composite::Unnamed(vec![]),
285 }),
286 context: type_id.clone(),
287 },
288 |inner_value| Value {
289 value: ValueDef::Variant(Variant {
290 name: variant_name.to_owned(),
291 values: inner_value,
292 }),
293 context: type_id.clone(),
294 },
295 );
296 Err(merged_error)
297 }
298 Ok(values) => Ok(Value {
299 value: ValueDef::Variant(Variant { name: variant_name.to_owned(), values }),
300 context: type_id,
301 }),
302 }
303 }
304
305 fn visit_composite<'scale, 'resolver>(
306 self,
307 value: &mut scale_decode::visitor::types::Composite<'scale, 'resolver, Self::TypeResolver>,
308 type_id: TypeIdFor<Self>,
309 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
310 let composite_vals = visit_composite(&self, value).map_err(|e| {
311 e.map_decoded_so_far(|c| Value {
312 value: ValueDef::Composite(c),
313 context: type_id.clone(),
314 })
315 })?;
316
317 Ok(Value { value: ValueDef::Composite(composite_vals), context: type_id })
318 }
319}
320
321fn visit_composite<R>(
322 this: &TraceDecodingVisitor<R>,
323 value: &mut scale_decode::visitor::types::Composite<'_, '_, R>,
324) -> Result<Composite<R::TypeId>, TraceDecodingError<Composite<R::TypeId>>>
325where
326 R: TypeResolver,
327{
328 let len = value.remaining();
329
330 let named = len > 0 && !value.has_unnamed_fields();
332
333 if !named {
335 return to_unnamed_composite!(this, value);
336 }
337
338 let mut vals = Vec::with_capacity(len);
340 let mut name = value.peek_name().unwrap_or("<unnamed>");
341
342 while let Some(val) = value.decode_item(this.at_field(name.to_owned())) {
343 match val {
344 Err(e) => {
345 let merged_error = e.with_outer_context(
346 || this.path.at_field(name.to_owned()),
347 || Composite::Named(vals.clone()),
348 |inner_value| {
349 let mut vals = vals.clone();
350 vals.push((name.to_owned(), inner_value));
351 Composite::Named(vals)
352 },
353 );
354 return Err(merged_error);
355 }
356 Ok(v) => {
357 vals.push((name.to_owned(), v));
358 }
359 }
360
361 name = value.peek_name().unwrap_or("<unnamed>");
362 }
363
364 Ok(Composite::Named(vals))
365}