twine-data 0.1.0

Codec for the twine-data binary serialization format
Documentation
//! Shallow values.

use crate::{
    types::{VariantIdx, Offset, Tag},
    Decoder, Immediate, Result,
};

/// A value, potentially containing other values.
///
/// Lifetime 'a is the lifetime of the decode (and string slices in it)
#[derive(Debug, Clone)]
pub enum ShallowValue<'a> {
    Imm(Immediate<'a>),
    Tag(Tag, Offset),
    Array(ArrayCursor<'a>),
    Map(MapCursor<'a>),
    Variant(VariantIdx, ArrayCursor<'a>),
}

#[derive(Debug, Clone)]
pub struct ArrayCursor<'a> {
    pub(crate) dec: Decoder<'a>,
    pub(crate) off: Offset,
    pub(crate) n_items: u32,
}

impl<'a> ArrayCursor<'a> {
    pub fn len(&self) -> usize {
        self.n_items as usize
    }
}

impl<'a> Iterator for ArrayCursor<'a> {
    type Item = Result<Offset>;

    fn next(&mut self) -> Option<Self::Item> {
        if self.n_items == 0 {
            return None;
        }

        let off = self.off;

        match self.dec.skip(off) {
            Ok(off2) => {
                self.off = off2;
                self.n_items -= 1;
                Some(Ok(off))
            }
            Err(e) => {
                self.n_items = 0;
                Some(Err(e))
            }
        }
    }
}

#[derive(Debug, Clone)]
pub struct MapCursor<'a> {
    pub(crate) dec: Decoder<'a>,
    pub(crate) off: Offset,
    pub(crate) n_items: u32,
}

impl<'a> MapCursor<'a> {
    pub fn len(&self) -> usize {
        self.n_items as usize
    }
}

impl<'a> Iterator for MapCursor<'a> {
    type Item = Result<(Offset, Offset)>;

    fn next(&mut self) -> Option<Self::Item> {
        if self.n_items == 0 {
            return None;
        }

        let k_off = self.off;

        match self.dec.skip(k_off) {
            Ok(v_off) => {
                self.off = v_off;

                match self.dec.skip(v_off) {
                    Ok(off2) => {
                        self.n_items -= 1;
                        self.off = off2;
                        Some(Ok((k_off, v_off)))
                    }
                    Err(e) => {
                        self.n_items = 0;
                        Some(Err(e))
                    }
                }
            }
            Err(e) => {
                self.n_items = 0;
                Some(Err(e))
            }
        }
    }
}