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