Skip to main content

nexus_decimal/
bytes.rs

1//! Byte serialization for `Decimal`.
2//!
3//! Inherent impls per backing type (not trait methods) since the
4//! return types differ by size. All methods are const fn.
5
6use crate::Decimal;
7
8// ============================================================================
9// i32 — 4 bytes
10// ============================================================================
11
12impl<const D: u8> Decimal<i32, D> {
13    /// Number of bytes in the serialized representation.
14    pub const BYTES: usize = 4;
15
16    /// Returns the underlying value as little-endian bytes.
17    #[inline(always)]
18    pub const fn to_le_bytes(self) -> [u8; 4] {
19        self.value.to_le_bytes()
20    }
21
22    /// Returns the underlying value as big-endian bytes.
23    #[inline(always)]
24    pub const fn to_be_bytes(self) -> [u8; 4] {
25        self.value.to_be_bytes()
26    }
27
28    /// Returns the underlying value as native-endian bytes.
29    #[inline(always)]
30    pub const fn to_ne_bytes(self) -> [u8; 4] {
31        self.value.to_ne_bytes()
32    }
33
34    /// Reconstructs a `Decimal` from its little-endian byte representation.
35    #[inline(always)]
36    pub const fn from_le_bytes(bytes: [u8; 4]) -> Self {
37        Self {
38            value: i32::from_le_bytes(bytes),
39        }
40    }
41
42    /// Reconstructs a `Decimal` from its big-endian byte representation.
43    #[inline(always)]
44    pub const fn from_be_bytes(bytes: [u8; 4]) -> Self {
45        Self {
46            value: i32::from_be_bytes(bytes),
47        }
48    }
49
50    /// Reconstructs a `Decimal` from its native-endian byte representation.
51    #[inline(always)]
52    pub const fn from_ne_bytes(bytes: [u8; 4]) -> Self {
53        Self {
54            value: i32::from_ne_bytes(bytes),
55        }
56    }
57
58    /// Writes little-endian bytes into `buf`. Panics if `buf.len() < 4`.
59    #[inline]
60    pub fn write_le_bytes(&self, buf: &mut [u8]) {
61        buf[..4].copy_from_slice(&self.to_le_bytes());
62    }
63
64    /// Writes big-endian bytes into `buf`. Panics if `buf.len() < 4`.
65    #[inline]
66    pub fn write_be_bytes(&self, buf: &mut [u8]) {
67        buf[..4].copy_from_slice(&self.to_be_bytes());
68    }
69
70    /// Reads little-endian bytes from `buf`. Panics if `buf.len() < 4`.
71    #[inline]
72    pub fn read_le_bytes(buf: &[u8]) -> Self {
73        let bytes: [u8; 4] = buf[..4]
74            .try_into()
75            .expect("buf[..4] always yields a 4-byte slice");
76        Self::from_le_bytes(bytes)
77    }
78
79    /// Reads big-endian bytes from `buf`. Panics if `buf.len() < 4`.
80    #[inline]
81    pub fn read_be_bytes(buf: &[u8]) -> Self {
82        let bytes: [u8; 4] = buf[..4]
83            .try_into()
84            .expect("buf[..4] always yields a 4-byte slice");
85        Self::from_be_bytes(bytes)
86    }
87}
88
89// ============================================================================
90// i64 — 8 bytes
91// ============================================================================
92
93impl<const D: u8> Decimal<i64, D> {
94    /// Number of bytes in the serialized representation.
95    pub const BYTES: usize = 8;
96
97    /// Returns the underlying value as little-endian bytes.
98    #[inline(always)]
99    pub const fn to_le_bytes(self) -> [u8; 8] {
100        self.value.to_le_bytes()
101    }
102
103    /// Returns the underlying value as big-endian bytes.
104    #[inline(always)]
105    pub const fn to_be_bytes(self) -> [u8; 8] {
106        self.value.to_be_bytes()
107    }
108
109    /// Returns the underlying value as native-endian bytes.
110    #[inline(always)]
111    pub const fn to_ne_bytes(self) -> [u8; 8] {
112        self.value.to_ne_bytes()
113    }
114
115    /// Reconstructs a `Decimal` from its little-endian byte representation.
116    #[inline(always)]
117    pub const fn from_le_bytes(bytes: [u8; 8]) -> Self {
118        Self {
119            value: i64::from_le_bytes(bytes),
120        }
121    }
122
123    /// Reconstructs a `Decimal` from its big-endian byte representation.
124    #[inline(always)]
125    pub const fn from_be_bytes(bytes: [u8; 8]) -> Self {
126        Self {
127            value: i64::from_be_bytes(bytes),
128        }
129    }
130
131    /// Reconstructs a `Decimal` from its native-endian byte representation.
132    #[inline(always)]
133    pub const fn from_ne_bytes(bytes: [u8; 8]) -> Self {
134        Self {
135            value: i64::from_ne_bytes(bytes),
136        }
137    }
138
139    /// Writes little-endian bytes into `buf`. Panics if `buf.len() < 8`.
140    #[inline]
141    pub fn write_le_bytes(&self, buf: &mut [u8]) {
142        buf[..8].copy_from_slice(&self.to_le_bytes());
143    }
144
145    /// Writes big-endian bytes into `buf`. Panics if `buf.len() < 8`.
146    #[inline]
147    pub fn write_be_bytes(&self, buf: &mut [u8]) {
148        buf[..8].copy_from_slice(&self.to_be_bytes());
149    }
150
151    /// Reads little-endian bytes from `buf`. Panics if `buf.len() < 8`.
152    #[inline]
153    pub fn read_le_bytes(buf: &[u8]) -> Self {
154        let bytes: [u8; 8] = buf[..8]
155            .try_into()
156            .expect("buf[..8] always yields an 8-byte slice");
157        Self::from_le_bytes(bytes)
158    }
159
160    /// Reads big-endian bytes from `buf`. Panics if `buf.len() < 8`.
161    #[inline]
162    pub fn read_be_bytes(buf: &[u8]) -> Self {
163        let bytes: [u8; 8] = buf[..8]
164            .try_into()
165            .expect("buf[..8] always yields an 8-byte slice");
166        Self::from_be_bytes(bytes)
167    }
168}
169
170// ============================================================================
171// i128 — 16 bytes
172// ============================================================================
173
174impl<const D: u8> Decimal<i128, D> {
175    /// Number of bytes in the serialized representation.
176    pub const BYTES: usize = 16;
177
178    /// Returns the underlying value as little-endian bytes.
179    #[inline(always)]
180    pub const fn to_le_bytes(self) -> [u8; 16] {
181        self.value.to_le_bytes()
182    }
183
184    /// Returns the underlying value as big-endian bytes.
185    #[inline(always)]
186    pub const fn to_be_bytes(self) -> [u8; 16] {
187        self.value.to_be_bytes()
188    }
189
190    /// Returns the underlying value as native-endian bytes.
191    #[inline(always)]
192    pub const fn to_ne_bytes(self) -> [u8; 16] {
193        self.value.to_ne_bytes()
194    }
195
196    /// Reconstructs a `Decimal` from its little-endian byte representation.
197    #[inline(always)]
198    pub const fn from_le_bytes(bytes: [u8; 16]) -> Self {
199        Self {
200            value: i128::from_le_bytes(bytes),
201        }
202    }
203
204    /// Reconstructs a `Decimal` from its big-endian byte representation.
205    #[inline(always)]
206    pub const fn from_be_bytes(bytes: [u8; 16]) -> Self {
207        Self {
208            value: i128::from_be_bytes(bytes),
209        }
210    }
211
212    /// Reconstructs a `Decimal` from its native-endian byte representation.
213    #[inline(always)]
214    pub const fn from_ne_bytes(bytes: [u8; 16]) -> Self {
215        Self {
216            value: i128::from_ne_bytes(bytes),
217        }
218    }
219
220    /// Writes little-endian bytes into `buf`. Panics if `buf.len() < 16`.
221    #[inline]
222    pub fn write_le_bytes(&self, buf: &mut [u8]) {
223        buf[..16].copy_from_slice(&self.to_le_bytes());
224    }
225
226    /// Writes big-endian bytes into `buf`. Panics if `buf.len() < 16`.
227    #[inline]
228    pub fn write_be_bytes(&self, buf: &mut [u8]) {
229        buf[..16].copy_from_slice(&self.to_be_bytes());
230    }
231
232    /// Reads little-endian bytes from `buf`. Panics if `buf.len() < 16`.
233    #[inline]
234    pub fn read_le_bytes(buf: &[u8]) -> Self {
235        let bytes: [u8; 16] = buf[..16]
236            .try_into()
237            .expect("buf[..16] always yields a 16-byte slice");
238        Self::from_le_bytes(bytes)
239    }
240
241    /// Reads big-endian bytes from `buf`. Panics if `buf.len() < 16`.
242    #[inline]
243    pub fn read_be_bytes(buf: &[u8]) -> Self {
244        let bytes: [u8; 16] = buf[..16]
245            .try_into()
246            .expect("buf[..16] always yields a 16-byte slice");
247        Self::from_be_bytes(bytes)
248    }
249}