commonware_utils/array/
u64.rs

1use crate::Array;
2use bytes::{Buf, BufMut};
3use commonware_codec::{Error as CodecError, FixedSize, Read, ReadExt, Write};
4use std::{
5    cmp::{Ord, PartialOrd},
6    fmt::{Debug, Display},
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    pub fn to_u64(&self) -> u64 {
30        u64::from_be_bytes(self.0)
31    }
32}
33
34impl Write for U64 {
35    fn write(&self, buf: &mut impl BufMut) {
36        self.0.write(buf);
37    }
38}
39
40impl Read for U64 {
41    fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, CodecError> {
42        <[u8; U64::SIZE]>::read(buf).map(Self)
43    }
44}
45
46impl FixedSize for U64 {
47    const SIZE: usize = u64::SIZE;
48}
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 AsRef<[u8]> for U64 {
59    fn as_ref(&self) -> &[u8] {
60        &self.0
61    }
62}
63
64impl Deref for U64 {
65    type Target = [u8];
66    fn deref(&self) -> &[u8] {
67        &self.0
68    }
69}
70
71impl Debug for U64 {
72    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73        write!(f, "{}", u64::from_be_bytes(self.0))
74    }
75}
76
77impl Display for U64 {
78    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79        write!(f, "{}", u64::from_be_bytes(self.0))
80    }
81}
82
83#[cfg(test)]
84mod tests {
85    use commonware_codec::{DecodeExt, Encode};
86
87    use super::*;
88
89    #[test]
90    fn test_u64() {
91        let value = 42u64;
92        let array = U64::new(value);
93        assert_eq!(value, U64::decode(array.as_ref()).unwrap().to_u64());
94        assert_eq!(value, U64::from(array.0).to_u64());
95
96        let vec = array.to_vec();
97        assert_eq!(value, U64::decode(vec.as_ref()).unwrap().to_u64());
98    }
99
100    #[test]
101    fn test_codec() {
102        let original = U64::new(42u64);
103
104        let encoded = original.encode();
105        assert_eq!(encoded.len(), U64::SIZE);
106        assert_eq!(encoded, original.as_ref());
107
108        let decoded = U64::decode(encoded).unwrap();
109        assert_eq!(original, decoded);
110    }
111}