kvds/
decode.rs

1#[derive(Debug)]
2pub enum DecodeError {
3    FileEndedUnexpectedly,
4}
5
6/// Decodes a Vec<u8> of data into a Vec of key-value pairs.
7///
8/// Note: This function cannot decode values that are more than 1.845*10^19 (or 256^8, or 2^64) bytes (or 18,447 petabytes) long.
9///
10/// # Example
11///
12/// ```rust
13/// # use kvds::DecodeError;
14/// #
15/// # fn main() -> Result<(), Box<DecodeError>> {
16/// #
17/// let data = vec![1, 0, 3, 111, 110, 101, 2, 0, 3, 116, 119, 111];
18///
19/// let decoded = kvds::decode(data)?;
20///
21/// assert_eq!(decoded, vec![
22///     (1, "one".as_bytes().to_vec()),
23///     (2, "two".as_bytes().to_vec()),
24/// ]);
25/// #
26/// # Ok(())
27/// # }
28/// ```
29///
30/// # Errors
31///
32/// This function returns an error if the data/file ends unexpectedly.
33pub fn decode(slice: Vec<u8>) -> Result<Vec<(u8, Vec<u8>)>, DecodeError> {
34    let mut vec = Vec::new();
35    let mut iter = slice.iter();
36
37    loop {
38        let key: u8;
39        if let Some(n) = iter.next() {
40            key = *n;
41        } else {
42            break;
43        }
44        let (digit1, digit2) = match (iter.next(), iter.next()) {
45            (Some(a), Some(b)) => (*a, *b),
46            _ => return Err(DecodeError::FileEndedUnexpectedly),
47        };
48
49        let mut number: u128 = u128::from(digit1) * 256u128 + u128::from(digit2);
50        if number == u16::max_value().into() {
51            number = 0;
52            for i in 1..=4 {
53                let digit = match iter.next() {
54                    Some(d) => *d,
55                    _ => return Err(DecodeError::FileEndedUnexpectedly),
56                };
57                number += u128::from(digit) * (256u128.pow(4 - i));
58            }
59            if number == u32::max_value().into() {
60                number = 0;
61                for i in 1..=8 {
62                    let digit = match iter.next() {
63                        Some(d) => *d,
64                        _ => return Err(DecodeError::FileEndedUnexpectedly),
65                    };
66                    number += u128::from(digit) * (256u128.pow(8 - i))
67                }
68                if number == u64::max_value().into() {
69                    number = 0;
70                    for i in 1..=16 {
71                        let digit = match iter.next() {
72                            Some(d) => *d,
73                            _ => return Err(DecodeError::FileEndedUnexpectedly),
74                        };
75                        number += u128::from(digit) * (256u128.pow(16 - i))
76                    }
77                }
78            }
79        }
80
81        let mut value = Vec::new();
82        for _ in 1..=number {
83            if let Some(n) = iter.next() {
84                value.push(*n)
85            } else {
86                return Err(DecodeError::FileEndedUnexpectedly);
87            }
88        }
89        vec.push((key, value));
90    }
91
92    Ok(vec)
93}