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