Skip to main content

substrate_data/wire/binary/decode/
decoder_value.rs

1//! [`Decoder`] reading a value as an owned [`Value`].
2
3use super::decoder::{F32_BYTES, F64_BYTES, MAP_ENTRY_MIN};
4use crate::binary::{DecodeError, Decoder, tag, unzigzag};
5use crate::model::value::{Map, Ref, RefKey, Value};
6
7/// The int a tag of its own is (`tag` at least [`tag::INT_INLINE`]).
8pub(in crate::wire::binary) fn inline_int(t: u8) -> i64 {
9    i64::from(t - tag::INT_INLINE) + crate::binary::INLINE_INT_MIN
10}
11
12impl Decoder<'_> {
13    /// The next value, owned.
14    ///
15    /// # Errors
16    ///
17    /// [`DecodeError`] when the bytes aren't a value.
18    pub fn value(&mut self) -> Result<Value, DecodeError> {
19        let t = self.byte()?;
20        Ok(match t {
21            tag::NULL => Value::Null,
22            tag::FALSE => Value::Bool(false),
23            tag::TRUE => Value::Bool(true),
24            tag::INT => Value::Int(unzigzag(self.varint()?)),
25            tag::FLOAT => Value::Float(f64::from_le_bytes(self.fixed()?)),
26            tag::FLOAT32 => Value::Float(f64::from(f32::from_le_bytes(self.fixed()?))),
27            tag::STR => Value::Str(self.string()?.to_owned()),
28            tag::LIST => self.list_value()?,
29            tag::MAP => self.map_value()?,
30            tag::REF => {
31                let (kind, id) = self.reference()?;
32                Value::Ref(Ref::new(kind, RefKey::spelled(id)))
33            }
34            tag::BYTES => Value::Bytes(self.length_bytes()?.to_vec()),
35            tag::STREAM => Value::List(self.stream_values()?),
36            tag::INTS | tag::FLOATS | tag::FLOATS32 => self.packed_value(t)?,
37            tag::MAP_SHAPE if self.v2 => {
38                let shape = self.shape_spec()?;
39                self.shaped_map_value(shape)?
40            }
41            tag::RECORDS if self.v2 => self.records_value()?,
42            t if self.is_inline_int(t) => Value::Int(inline_int(t)),
43            t if self.is_indexed(t) => Value::Str(self.indexed(t)?.to_owned()),
44            _ => {
45                self.i -= 1;
46                return Err(self.error(format!("unknown tag {t}")));
47            }
48        })
49    }
50
51    fn list_value(&mut self) -> Result<Value, DecodeError> {
52        let n = self.count(1)?;
53        self.deeper()?;
54        let mut items = Vec::with_capacity(n);
55        for _ in 0..n {
56            items.push(self.value()?);
57        }
58        self.depth -= 1;
59        Ok(Value::List(items))
60    }
61
62    fn map_value(&mut self) -> Result<Value, DecodeError> {
63        let n = self.count(MAP_ENTRY_MIN)?;
64        self.deeper()?;
65        let mut map = Map::with_capacity(n);
66        for _ in 0..n {
67            let at = self.i;
68            let i = self.string_index()?;
69            if map.index_of(self.strings[i]).is_some() {
70                return Err(DecodeError::duplicate_key(self.strings[i], at));
71            }
72            let k = self.shared_key_at(i);
73            map.push_unchecked(k, self.value()?);
74        }
75        self.depth -= 1;
76        Ok(Value::Map(map))
77    }
78
79    /// A map of shape `shape`: its values, one per key.
80    fn shaped_map_value(&mut self, shape: usize) -> Result<Value, DecodeError> {
81        let n = self.shape_width(shape)?;
82        self.deeper()?;
83        let map = self.shaped_entries(shape, n)?;
84        self.depth -= 1;
85        Ok(Value::Map(map))
86    }
87
88    fn shaped_entries(&mut self, shape: usize, n: usize) -> Result<Map, DecodeError> {
89        let mut map = Map::with_capacity(n);
90        for at in 0..n {
91            let k = self.shared_key_at(self.shapes.key(shape, at));
92            map.push_unchecked(k, self.value()?);
93        }
94        Ok(map)
95    }
96
97    /// A list of maps of one shape: a count, the shape, the values.
98    fn records_value(&mut self) -> Result<Value, DecodeError> {
99        let n = self.count(1)?;
100        let shape = self.shape_spec()?;
101        let width = self.shapes.width(shape);
102        let left = self.b.len() - self.i;
103        if n > left / width {
104            return Err(self.error(format!("length {n} past the end ({left} bytes left)")));
105        }
106        self.deeper()?;
107        let mut items = Vec::with_capacity(n);
108        for _ in 0..n {
109            self.deeper()?;
110            items.push(Value::Map(self.shaped_entries(shape, width)?));
111            self.depth -= 1;
112        }
113        self.depth -= 1;
114        Ok(Value::List(items))
115    }
116
117    /// A packed list of ints (`t` is [`tag::INTS`]) or floats.
118    fn packed_value(&mut self, t: u8) -> Result<Value, DecodeError> {
119        Ok(Value::List(match t {
120            tag::INTS => {
121                let n = self.count(1)?;
122                let mut items = Vec::with_capacity(n);
123                for _ in 0..n {
124                    items.push(Value::Int(unzigzag(self.varint()?)));
125                }
126                items
127            }
128            tag::FLOATS => self
129                .packed_floats::<F64_BYTES>()?
130                .map(|f| Value::Float(f64::from_le_bytes(*f)))
131                .collect(),
132            _ => self
133                .packed_floats::<F32_BYTES>()?
134                .map(|f| Value::Float(f64::from(f32::from_le_bytes(*f))))
135                .collect(),
136        }))
137    }
138}