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#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
22#[repr(transparent)]
23pub struct U64([u8; u64::SIZE]);
24
25impl U64 {
26    pub const fn new(value: u64) -> Self {
27        Self(value.to_be_bytes())
28    }
29}
30
31impl Write for U64 {
32    fn write(&self, buf: &mut impl BufMut) {
33        self.0.write(buf);
34    }
35}
36
37impl Read for U64 {
38    type Cfg = ();
39
40    fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, CodecError> {
41        <[u8; Self::SIZE]>::read(buf).map(Self)
42    }
43}
44
45impl FixedSize for U64 {
46    const SIZE: usize = u64::SIZE;
47}
48
49impl Span for U64 {}
50
51impl Array for U64 {}
52
53impl From<[u8; Self::SIZE]> for U64 {
54    fn from(value: [u8; Self::SIZE]) -> Self {
55        Self(value)
56    }
57}
58
59impl From<u64> for U64 {
60    fn from(value: u64) -> Self {
61        Self(value.to_be_bytes())
62    }
63}
64
65impl From<U64> for u64 {
66    fn from(value: U64) -> Self {
67        Self::from_be_bytes(value.0)
68    }
69}
70
71impl From<&U64> for u64 {
72    fn from(value: &U64) -> Self {
73        Self::from_be_bytes(value.0)
74    }
75}
76
77impl AsRef<[u8]> for U64 {
78    fn as_ref(&self) -> &[u8] {
79        &self.0
80    }
81}
82
83impl Deref for U64 {
84    type Target = [u8];
85    fn deref(&self) -> &[u8] {
86        &self.0
87    }
88}
89
90impl Debug for U64 {
91    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
92        write!(f, "{}", u64::from_be_bytes(self.0))
93    }
94}
95
96impl Display for U64 {
97    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
98        write!(f, "{}", u64::from_be_bytes(self.0))
99    }
100}
101
102#[cfg(test)]
103mod tests {
104    use super::*;
105    use commonware_codec::{DecodeExt, Encode};
106
107    #[test]
108    fn test_u64() {
109        let value = 42u64;
110        let array = U64::new(value);
111        assert_eq!(value, U64::decode(array.as_ref()).unwrap().into());
112        assert_eq!(value, U64::from(array.0).into());
113
114        let vec = array.to_vec();
115        assert_eq!(value, U64::decode(vec.as_ref()).unwrap().into());
116    }
117
118    #[test]
119    fn test_codec() {
120        let original = U64::new(42u64);
121
122        let encoded = original.encode();
123        assert_eq!(encoded.len(), U64::SIZE);
124        assert_eq!(encoded, original.as_ref());
125
126        let decoded = U64::decode(encoded).unwrap();
127        assert_eq!(original, decoded);
128    }
129
130    #[cfg(feature = "arbitrary")]
131    mod conformance {
132        use super::*;
133        use commonware_codec::conformance::CodecConformance;
134
135        commonware_conformance::conformance_tests! {
136            CodecConformance<U64>,
137        }
138    }
139}