uts-core 0.1.0-alpha.1

Core types and traits for Univeral Timestamps in Rust
Documentation
use super::*;
use crate::{
    codec::{Decode, DecodeIn, Decoder},
    error::DecodeError,
};

const RECURSION_LIMIT: usize = 256;

impl<A: Allocator + Clone> DecodeIn<A> for Timestamp<A> {
    fn decode_in(decoder: &mut impl Decoder, alloc: A) -> Result<Self, DecodeError> {
        Self::decode_recursive(decoder, RECURSION_LIMIT, alloc)
    }
}

impl<A: Allocator + Clone> Timestamp<A> {
    fn decode_recursive(
        decoder: &mut impl Decoder,
        recursion_limit: usize,
        alloc: A,
    ) -> Result<Timestamp<A>, DecodeError> {
        if recursion_limit == 0 {
            return Err(DecodeError::RecursionLimit);
        }
        let op = OpCode::decode(&mut *decoder)?;

        Self::decode_from_op(op, decoder, recursion_limit, alloc)
    }

    fn decode_from_op(
        op: OpCode,
        decoder: &mut impl Decoder,
        limit: usize,
        alloc: A,
    ) -> Result<Timestamp<A>, DecodeError> {
        match op {
            OpCode::ATTESTATION => {
                let attestation = RawAttestation::decode_in(decoder, alloc)?;
                Ok(Timestamp::Attestation(attestation))
            }
            OpCode::FORK => {
                let mut children = Vec::new_in(alloc.clone());
                let mut next_op = OpCode::FORK;
                while next_op == OpCode::FORK {
                    let child = Self::decode_recursive(&mut *decoder, limit - 1, alloc.clone())?;
                    children.push(child);
                    next_op = OpCode::decode(&mut *decoder)?;
                }
                children.push(Self::decode_from_op(
                    next_op,
                    decoder,
                    limit - 1,
                    alloc.clone(),
                )?);
                Ok(Timestamp::Step(Step {
                    op: OpCode::FORK,
                    data: Vec::new_in(alloc),
                    input: OnceLock::new(),
                    next: children,
                }))
            }
            _ => {
                let data = if op.has_immediate() {
                    const MAX_OP_LENGTH: usize = 4096;
                    let length = decoder.decode_ranged(1..=MAX_OP_LENGTH)?;
                    let mut data = Vec::with_capacity_in(length, alloc.clone());
                    data.resize(length, 0);
                    decoder.read_exact(&mut data)?;

                    data
                } else {
                    Vec::new_in(alloc.clone())
                };

                let mut next = Vec::with_capacity_in(1, alloc.clone());
                next.push(Self::decode_recursive(decoder, limit - 1, alloc)?);

                Ok(Timestamp::Step(Step {
                    op,
                    data,
                    input: OnceLock::new(),
                    next,
                }))
            }
        }
    }
}