1use crate::{Error, Result};
2
3#[derive(Clone, Debug, Eq, PartialEq)]
8pub enum Lengths {
9 U16(Vec<u16>),
11 U32(Vec<u32>),
13 U64(Vec<u64>),
15}
16
17impl Lengths {
18 pub fn new(max_length: u64) -> Result<Self> {
20 match max_length {
21 0 => Err(Error::InvalidFrameSize),
22 1..=65_536 => Ok(Self::U16(Vec::new())),
23 65_537..=4_294_967_296 => Ok(Self::U32(Vec::new())),
24 _ => Ok(Self::U64(Vec::new())),
25 }
26 }
27
28 pub fn len(&self) -> usize {
30 match self {
31 Self::U16(v) => v.len(),
32 Self::U32(v) => v.len(),
33 Self::U64(v) => v.len(),
34 }
35 }
36 pub fn is_empty(&self) -> bool {
38 self.len() == 0
39 }
40 pub fn width(&self) -> usize {
42 match self {
43 Self::U16(_) => 2,
44 Self::U32(_) => 4,
45 Self::U64(_) => 8,
46 }
47 }
48 pub fn get(&self, index: usize) -> Option<u64> {
50 match self {
51 Self::U16(v) => v.get(index).map(|v| u64::from(*v) + 1),
52 Self::U32(v) => v.get(index).map(|v| u64::from(*v) + 1),
53 Self::U64(v) => v.get(index).and_then(|v| v.checked_add(1)),
54 }
55 }
56 pub fn push(&mut self, length: u64) -> Result<()> {
58 let encoded = length.checked_sub(1).ok_or(Error::InvalidFrameSize)?;
59 match self {
60 Self::U16(v) => {
61 let value = u16::try_from(encoded).map_err(|_| Error::Overflow)?;
62 v.try_reserve(1).map_err(|_| Error::Allocation)?;
63 v.push(value);
64 }
65 Self::U32(v) => {
66 let value = u32::try_from(encoded).map_err(|_| Error::Overflow)?;
67 v.try_reserve(1).map_err(|_| Error::Allocation)?;
68 v.push(value);
69 }
70 Self::U64(v) => {
71 v.try_reserve(1).map_err(|_| Error::Allocation)?;
72 v.push(encoded);
73 }
74 }
75 Ok(())
76 }
77 pub(crate) fn reserve_one(&mut self) -> Result<()> {
78 match self {
79 Self::U16(v) => v.try_reserve(1),
80 Self::U32(v) => v.try_reserve(1),
81 Self::U64(v) => v.try_reserve(1),
82 }
83 .map_err(|_| Error::Allocation)
84 }
85}