substrate_data/wire/binary/
decoder_ref.rs1use bumpalo::Bump;
5
6use super::decoder::{F32_BYTES, F64_BYTES, MAP_ENTRY_MIN};
7use super::seen_keys::SeenKeys;
8use super::{DecodeError, Decoder, tag, unzigzag};
9use crate::model::borrowed::{MapRef, ValueRef};
10
11impl<'b> Decoder<'b> {
12 pub fn value_ref<'a>(&mut self, arena: &'a Bump) -> Result<ValueRef<'a>, DecodeError>
18 where
19 'b: 'a,
20 {
21 let mut stack = Vec::new();
22 self.value_ref_in(arena, &mut stack)
23 }
24
25 fn value_ref_in<'a>(
27 &mut self,
28 arena: &'a Bump,
29 stack: &mut Vec<ValueRef<'a>>,
30 ) -> Result<ValueRef<'a>, DecodeError>
31 where
32 'b: 'a,
33 {
34 Ok(match self.byte()? {
35 tag::NULL => ValueRef::Null,
36 tag::FALSE => ValueRef::Bool(false),
37 tag::TRUE => ValueRef::Bool(true),
38 tag::INT => ValueRef::Int(unzigzag(self.varint()?)),
39 tag::FLOAT => ValueRef::Float(f64::from_le_bytes(self.fixed()?)),
40 tag::FLOAT32 => ValueRef::Float(f64::from(f32::from_le_bytes(self.fixed()?))),
41 t @ (tag::FLOATS | tag::FLOATS32) => self.floats_ref(arena, t == tag::FLOATS)?,
42 tag::STR => ValueRef::Str(self.string()?),
43 tag::LIST => {
44 let n = self.count(1)?;
45 self.deeper()?;
46 let items = self.items_ref(arena, stack, n)?;
47 self.depth -= 1;
48 ValueRef::List(items)
49 }
50 tag::MAP => self.map_ref(arena, stack)?,
51 tag::REF => {
52 let (kind, id) = self.reference()?;
53 ValueRef::Ref { kind, id }
54 }
55 tag::BYTES => ValueRef::Bytes(self.length_bytes()?),
56 tag::INTS => self.ints_ref(arena)?,
57 tag::STREAM => {
58 let mut d = Decoder::body(self.stream_body()?);
59 d.depth = self.depth;
60 let n = d.count(1)?;
61 let items = d.items_ref(arena, stack, n)?;
62 d.end()?;
63 ValueRef::List(items)
64 }
65 t => {
66 self.i -= 1;
67 return Err(self.error(format!("unknown tag {t}")));
68 }
69 })
70 }
71
72 fn items_ref<'a>(
74 &mut self,
75 arena: &'a Bump,
76 stack: &mut Vec<ValueRef<'a>>,
77 n: usize,
78 ) -> Result<&'a [ValueRef<'a>], DecodeError>
79 where
80 'b: 'a,
81 {
82 let start = stack.len();
83 for _ in 0..n {
84 let v = self.value_ref_in(arena, stack)?;
85 stack.push(v);
86 }
87 let items = arena.alloc_slice_copy(&stack[start..]);
88 stack.truncate(start);
89 Ok(items)
90 }
91
92 fn map_ref<'a>(
93 &mut self,
94 arena: &'a Bump,
95 stack: &mut Vec<ValueRef<'a>>,
96 ) -> Result<ValueRef<'a>, DecodeError>
97 where
98 'b: 'a,
99 {
100 let n = self.count(MAP_ENTRY_MIN)?;
101 self.deeper()?;
102 let mut entries = bumpalo::collections::Vec::with_capacity_in(n, arena);
103 let mut seen = SeenKeys::default();
104 for _ in 0..n {
105 let at = self.i;
106 let k = self.string()?;
107 if !seen.insert(k) {
108 return Err(DecodeError::duplicate_key(k, at));
109 }
110 entries.push((k, self.value_ref_in(arena, stack)?));
111 }
112 self.depth -= 1;
113 Ok(ValueRef::Map(MapRef(entries.into_bump_slice())))
114 }
115
116 fn ints_ref<'a>(&mut self, arena: &'a Bump) -> Result<ValueRef<'a>, DecodeError> {
117 let n = self.count(1)?;
118 let mut items = bumpalo::collections::Vec::with_capacity_in(n, arena);
119 for _ in 0..n {
120 items.push(ValueRef::Int(unzigzag(self.varint()?)));
121 }
122 Ok(ValueRef::List(items.into_bump_slice()))
123 }
124
125 fn floats_ref<'a>(&mut self, arena: &'a Bump, wide: bool) -> Result<ValueRef<'a>, DecodeError> {
127 let items: Vec<ValueRef<'a>> = if wide {
128 self.packed_floats::<F64_BYTES>()?
129 .map(|f| ValueRef::Float(f64::from_le_bytes(*f)))
130 .collect()
131 } else {
132 self.packed_floats::<F32_BYTES>()?
133 .map(|f| ValueRef::Float(f64::from(f32::from_le_bytes(*f))))
134 .collect()
135 };
136 Ok(ValueRef::List(arena.alloc_slice_copy(&items)))
137 }
138}