commonware_utils/array/
u64.rs1use crate::{Array, SizedSerialize};
2use std::{
3 cmp::{Ord, PartialOrd},
4 fmt::{Debug, Display},
5 hash::Hash,
6 ops::Deref,
7};
8use thiserror::Error;
9
10#[derive(Error, Debug, PartialEq)]
12pub enum Error {
13 #[error("invalid length")]
14 InvalidLength,
15}
16
17#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
19#[repr(transparent)]
20pub struct U64([u8; U64::SERIALIZED_LEN]);
21
22impl U64 {
23 pub fn new(value: u64) -> Self {
24 Self(value.to_be_bytes())
25 }
26
27 pub fn to_u64(&self) -> u64 {
28 u64::from_be_bytes(self.0)
29 }
30}
31
32impl Array for U64 {
33 type Error = Error;
34}
35
36impl SizedSerialize for U64 {
37 const SERIALIZED_LEN: usize = u64::SERIALIZED_LEN;
38}
39
40impl From<[u8; U64::SERIALIZED_LEN]> for U64 {
41 fn from(value: [u8; U64::SERIALIZED_LEN]) -> Self {
42 Self(value)
43 }
44}
45
46impl TryFrom<&[u8]> for U64 {
47 type Error = Error;
48
49 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
50 if value.len() != U64::SERIALIZED_LEN {
51 return Err(Error::InvalidLength);
52 }
53 let array: [u8; U64::SERIALIZED_LEN] =
54 value.try_into().map_err(|_| Error::InvalidLength)?;
55 Ok(Self(array))
56 }
57}
58
59impl TryFrom<&Vec<u8>> for U64 {
60 type Error = Error;
61
62 fn try_from(value: &Vec<u8>) -> Result<Self, Self::Error> {
63 Self::try_from(value.as_slice())
64 }
65}
66
67impl TryFrom<Vec<u8>> for U64 {
68 type Error = Error;
69
70 fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
71 if value.len() != U64::SERIALIZED_LEN {
72 return Err(Error::InvalidLength);
73 }
74
75 let boxed_slice = value.into_boxed_slice();
78 let boxed_array: Box<[u8; U64::SERIALIZED_LEN]> =
79 boxed_slice.try_into().map_err(|_| Error::InvalidLength)?;
80 Ok(Self(*boxed_array))
81 }
82}
83
84impl AsRef<[u8]> for U64 {
85 fn as_ref(&self) -> &[u8] {
86 &self.0
87 }
88}
89
90impl Deref for U64 {
91 type Target = [u8];
92 fn deref(&self) -> &[u8] {
93 &self.0
94 }
95}
96
97impl Debug for U64 {
98 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99 write!(f, "{}", u64::from_be_bytes(self.0))
100 }
101}
102
103impl Display for U64 {
104 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
105 write!(f, "{}", u64::from_be_bytes(self.0))
106 }
107}
108
109#[cfg(test)]
110mod tests {
111 use super::*;
112
113 #[test]
114 fn test_u64() {
115 let value = 42u64;
116 let array = U64::new(value);
117 assert_eq!(value, U64::try_from(array.as_ref()).unwrap().to_u64());
118 assert_eq!(value, U64::from(array.0).to_u64());
119
120 let vec = array.to_vec();
121 assert_eq!(value, U64::try_from(&vec).unwrap().to_u64());
122 assert_eq!(value, U64::try_from(vec).unwrap().to_u64());
123 }
124}