uts_core/codec/v1/timestamp/
decode.rs1use super::*;
2use crate::{
3 codec::{Decode, DecodeIn, Decoder},
4 error::DecodeError,
5};
6
7const RECURSION_LIMIT: usize = 256;
8
9impl<A: Allocator + Clone> DecodeIn<A> for Timestamp<A> {
10 fn decode_in(decoder: &mut impl Decoder, alloc: A) -> Result<Self, DecodeError> {
11 Self::decode_recursive(decoder, RECURSION_LIMIT, alloc)
12 }
13}
14
15impl<A: Allocator + Clone> Timestamp<A> {
16 fn decode_recursive(
17 decoder: &mut impl Decoder,
18 recursion_limit: usize,
19 alloc: A,
20 ) -> Result<Timestamp<A>, DecodeError> {
21 if recursion_limit == 0 {
22 return Err(DecodeError::RecursionLimit);
23 }
24 let op = OpCode::decode(&mut *decoder)?;
25
26 Self::decode_from_op(op, decoder, recursion_limit, alloc)
27 }
28
29 fn decode_from_op(
30 op: OpCode,
31 decoder: &mut impl Decoder,
32 limit: usize,
33 alloc: A,
34 ) -> Result<Timestamp<A>, DecodeError> {
35 match op {
36 OpCode::ATTESTATION => {
37 let attestation = RawAttestation::decode_in(decoder, alloc)?;
38 Ok(Timestamp::Attestation(attestation))
39 }
40 OpCode::FORK => {
41 let mut children = Vec::new_in(alloc.clone());
42 let mut next_op = OpCode::FORK;
43 while next_op == OpCode::FORK {
44 let child = Self::decode_recursive(&mut *decoder, limit - 1, alloc.clone())?;
45 children.push(child);
46 next_op = OpCode::decode(&mut *decoder)?;
47 }
48 children.push(Self::decode_from_op(
49 next_op,
50 decoder,
51 limit - 1,
52 alloc.clone(),
53 )?);
54 Ok(Timestamp::Step(Step {
55 op: OpCode::FORK,
56 data: Vec::new_in(alloc),
57 input: OnceLock::new(),
58 next: children,
59 }))
60 }
61 _ => {
62 let data = if op.has_immediate() {
63 const MAX_OP_LENGTH: usize = 4096;
64 let length = decoder.decode_ranged(1..=MAX_OP_LENGTH)?;
65 let mut data = Vec::with_capacity_in(length, alloc.clone());
66 data.resize(length, 0);
67 decoder.read_exact(&mut data)?;
68
69 data
70 } else {
71 Vec::new_in(alloc.clone())
72 };
73
74 let mut next = Vec::with_capacity_in(1, alloc.clone());
75 next.push(Self::decode_recursive(decoder, limit - 1, alloc)?);
76
77 Ok(Timestamp::Step(Step {
78 op,
79 data,
80 input: OnceLock::new(),
81 next,
82 }))
83 }
84 }
85 }
86}