commonware_utils/sequence/
u64.rs

1use crate::{Array, Span};
2use bytes::{Buf, BufMut};
3use commonware_codec::{Error as CodecError, FixedSize, Read, ReadExt, Write};
4use core::{
5    cmp::{Ord, PartialOrd},
6    fmt::{Debug, Display, Formatter},
7    hash::Hash,
8    ops::Deref,
9};
10use thiserror::Error;
11
12// Errors returned by `U64` functions.
13#[derive(Error, Debug, PartialEq)]
14pub enum Error {
15    #[error("invalid length")]
16    InvalidLength,
17}
18
19/// An `Array` implementation for `u64`.
20#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
21#[repr(transparent)]
22pub struct U64([u8; u64::SIZE]);
23
24impl U64 {
25    pub fn new(value: u64) -> Self {
26        Self(value.to_be_bytes())
27    }
28}
29
30impl Write for U64 {
31    fn write(&self, buf: &mut impl BufMut) {
32        self.0.write(buf);
33    }
34}
35
36impl Read for U64 {
37    type Cfg = ();
38
39    fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, CodecError> {
40        <[u8; U64::SIZE]>::read(buf).map(Self)
41    }
42}
43
44impl FixedSize for U64 {
45    const SIZE: usize = u64::SIZE;
46}
47
48impl Span for U64 {}
49
50impl Array for U64 {}
51
52impl From<[u8; U64::SIZE]> for U64 {
53    fn from(value: [u8; U64::SIZE]) -> Self {
54        Self(value)
55    }
56}
57
58impl From<u64> for U64 {
59    fn from(value: u64) -> Self {
60        Self(value.to_be_bytes())
61    }
62}
63
64impl From<U64> for u64 {
65    fn from(value: U64) -> Self {
66        u64::from_be_bytes(value.0)
67    }
68}
69
70impl From<&U64> for u64 {
71    fn from(value: &U64) -> Self {
72        u64::from_be_bytes(value.0)
73    }
74}
75
76impl AsRef<[u8]> for U64 {
77    fn as_ref(&self) -> &[u8] {
78        &self.0
79    }
80}
81
82impl Deref for U64 {
83    type Target = [u8];
84    fn deref(&self) -> &[u8] {
85        &self.0
86    }
87}
88
89impl Debug for U64 {
90    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
91        write!(f, "{}", u64::from_be_bytes(self.0))
92    }
93}
94
95impl Display for U64 {
96    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
97        write!(f, "{}", u64::from_be_bytes(self.0))
98    }
99}
100
101#[cfg(test)]
102mod tests {
103    use super::*;
104    use commonware_codec::{DecodeExt, Encode};
105
106    #[test]
107    fn test_u64() {
108        let value = 42u64;
109        let array = U64::new(value);
110        assert_eq!(value, U64::decode(array.as_ref()).unwrap().into());
111        assert_eq!(value, U64::from(array.0).into());
112
113        let vec = array.to_vec();
114        assert_eq!(value, U64::decode(vec.as_ref()).unwrap().into());
115    }
116
117    #[test]
118    fn test_codec() {
119        let original = U64::new(42u64);
120
121        let encoded = original.encode();
122        assert_eq!(encoded.len(), U64::SIZE);
123        assert_eq!(encoded, original.as_ref());
124
125        let decoded = U64::decode(encoded).unwrap();
126        assert_eq!(original, decoded);
127    }
128}