commonware_utils/sequence/
u64.rs1use 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#[derive(Error, Debug, PartialEq)]
14pub enum Error {
15 #[error("invalid length")]
16 InvalidLength,
17}
18
19#[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}