Skip to main content

object_rainbow/
u63.rs

1use crate::*;
2
3#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, ParseAsInline)]
4pub struct U63(u64);
5
6impl U63 {
7    pub fn from_u64(n: u64) -> crate::Result<Self> {
8        if n < ((1 << 63) + 128) {
9            Ok(Self(n))
10        } else {
11            Err(Error::UnsupportedLength)
12        }
13    }
14
15    pub fn as_usize(self) -> crate::Result<usize> {
16        self.0.try_into().map_err(|_| Error::UnsupportedLength)
17    }
18
19    pub fn len_of<T>(v: &[T]) -> Self {
20        Self::from_u64(v.len() as _).expect("this is unreasonable to store in memory")
21    }
22}
23
24impl ToOutput for U63 {
25    fn to_output(&self, output: &mut impl Output) {
26        if self.0 < 128 {
27            (self.0 as u8).to_output(output);
28        } else {
29            let mut bytes = (self.0 - 128).to_be_bytes();
30            bytes[0] ^= 128;
31            bytes.to_output(output);
32        }
33    }
34}
35
36impl InlineOutput for U63 {}
37impl Tagged for U63 {}
38impl ListHashes for U63 {}
39impl Topological for U63 {}
40
41impl<I: ParseInput> ParseInline<I> for U63 {
42    fn parse_inline(input: &mut I) -> crate::Result<Self> {
43        let mut bytes = [0; 8];
44        input.read(&mut bytes[..1])?;
45        Ok(Self(if bytes[0] & 128 == 0 {
46            bytes[0] as u64
47        } else {
48            bytes[0] ^= 128;
49            input.read(&mut bytes[1..])?;
50            u64::from_be_bytes(bytes) + 128
51        }))
52    }
53}