twine_data/
shallow_value.rs

1//! Shallow values.
2
3use crate::{
4    types::{VariantIdx, Offset, Tag},
5    Decoder, Immediate, Result,
6};
7
8/// A value, potentially containing other values.
9///
10/// Lifetime 'a is the lifetime of the decode (and string slices in it)
11#[derive(Debug, Clone)]
12pub enum ShallowValue<'a> {
13    Imm(Immediate<'a>),
14    Tag(Tag, Offset),
15    Array(ArrayCursor<'a>),
16    Map(MapCursor<'a>),
17    Variant(VariantIdx, ArrayCursor<'a>),
18}
19
20#[derive(Debug, Clone)]
21pub struct ArrayCursor<'a> {
22    pub(crate) dec: Decoder<'a>,
23    pub(crate) off: Offset,
24    pub(crate) n_items: u32,
25}
26
27impl<'a> ArrayCursor<'a> {
28    pub fn len(&self) -> usize {
29        self.n_items as usize
30    }
31}
32
33impl<'a> Iterator for ArrayCursor<'a> {
34    type Item = Result<Offset>;
35
36    fn next(&mut self) -> Option<Self::Item> {
37        if self.n_items == 0 {
38            return None;
39        }
40
41        let off = self.off;
42
43        match self.dec.skip(off) {
44            Ok(off2) => {
45                self.off = off2;
46                self.n_items -= 1;
47                Some(Ok(off))
48            }
49            Err(e) => {
50                self.n_items = 0;
51                Some(Err(e))
52            }
53        }
54    }
55}
56
57#[derive(Debug, Clone)]
58pub struct MapCursor<'a> {
59    pub(crate) dec: Decoder<'a>,
60    pub(crate) off: Offset,
61    pub(crate) n_items: u32,
62}
63
64impl<'a> MapCursor<'a> {
65    pub fn len(&self) -> usize {
66        self.n_items as usize
67    }
68}
69
70impl<'a> Iterator for MapCursor<'a> {
71    type Item = Result<(Offset, Offset)>;
72
73    fn next(&mut self) -> Option<Self::Item> {
74        if self.n_items == 0 {
75            return None;
76        }
77
78        let k_off = self.off;
79
80        match self.dec.skip(k_off) {
81            Ok(v_off) => {
82                self.off = v_off;
83
84                match self.dec.skip(v_off) {
85                    Ok(off2) => {
86                        self.n_items -= 1;
87                        self.off = off2;
88                        Some(Ok((k_off, v_off)))
89                    }
90                    Err(e) => {
91                        self.n_items = 0;
92                        Some(Err(e))
93                    }
94                }
95            }
96            Err(e) => {
97                self.n_items = 0;
98                Some(Err(e))
99            }
100        }
101    }
102}