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