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