Skip to main content

nros_serdes/
primitives.rs

1//! [`Serialize`] and [`Deserialize`] implementations for primitive types.
2//!
3//! Covers: `bool`, `u8`–`u64`, `i8`–`i64`, `f32`, `f64`, `char`, `&str`,
4//! fixed-size arrays, `heapless::String`, and `heapless::Vec`.
5//! With the `alloc` feature: `String` and `Vec<T>`.
6
7use crate::{
8    cdr::{CdrReader, CdrWriter},
9    error::{DeserError, SerError},
10    traits::{Deserialize, Serialize},
11};
12
13// === Boolean ===
14
15impl Serialize for bool {
16    #[inline]
17    fn serialize(&self, writer: &mut CdrWriter) -> Result<(), SerError> {
18        writer.write_u8(if *self { 1 } else { 0 })
19    }
20}
21
22impl Deserialize for bool {
23    #[inline]
24    fn deserialize(reader: &mut CdrReader) -> Result<Self, DeserError> {
25        Ok(reader.read_u8()? != 0)
26    }
27}
28
29// === 8-bit integers ===
30
31impl Serialize for u8 {
32    #[inline]
33    fn serialize(&self, writer: &mut CdrWriter) -> Result<(), SerError> {
34        writer.write_u8(*self)
35    }
36}
37
38impl Deserialize for u8 {
39    #[inline]
40    fn deserialize(reader: &mut CdrReader) -> Result<Self, DeserError> {
41        reader.read_u8()
42    }
43}
44
45impl Serialize for i8 {
46    #[inline]
47    fn serialize(&self, writer: &mut CdrWriter) -> Result<(), SerError> {
48        writer.write_u8(*self as u8)
49    }
50}
51
52impl Deserialize for i8 {
53    #[inline]
54    fn deserialize(reader: &mut CdrReader) -> Result<Self, DeserError> {
55        Ok(reader.read_u8()? as i8)
56    }
57}
58
59// === 16-bit integers ===
60
61impl Serialize for u16 {
62    #[inline]
63    fn serialize(&self, writer: &mut CdrWriter) -> Result<(), SerError> {
64        writer.write_u16(*self)
65    }
66}
67
68impl Deserialize for u16 {
69    #[inline]
70    fn deserialize(reader: &mut CdrReader) -> Result<Self, DeserError> {
71        reader.read_u16()
72    }
73}
74
75impl Serialize for i16 {
76    #[inline]
77    fn serialize(&self, writer: &mut CdrWriter) -> Result<(), SerError> {
78        writer.write_i16(*self)
79    }
80}
81
82impl Deserialize for i16 {
83    #[inline]
84    fn deserialize(reader: &mut CdrReader) -> Result<Self, DeserError> {
85        reader.read_i16()
86    }
87}
88
89// === 32-bit integers ===
90
91impl Serialize for u32 {
92    #[inline]
93    fn serialize(&self, writer: &mut CdrWriter) -> Result<(), SerError> {
94        writer.write_u32(*self)
95    }
96}
97
98impl Deserialize for u32 {
99    #[inline]
100    fn deserialize(reader: &mut CdrReader) -> Result<Self, DeserError> {
101        reader.read_u32()
102    }
103}
104
105impl Serialize for i32 {
106    #[inline]
107    fn serialize(&self, writer: &mut CdrWriter) -> Result<(), SerError> {
108        writer.write_i32(*self)
109    }
110}
111
112impl Deserialize for i32 {
113    #[inline]
114    fn deserialize(reader: &mut CdrReader) -> Result<Self, DeserError> {
115        reader.read_i32()
116    }
117}
118
119// === 64-bit integers ===
120
121impl Serialize for u64 {
122    #[inline]
123    fn serialize(&self, writer: &mut CdrWriter) -> Result<(), SerError> {
124        writer.write_u64(*self)
125    }
126}
127
128impl Deserialize for u64 {
129    #[inline]
130    fn deserialize(reader: &mut CdrReader) -> Result<Self, DeserError> {
131        reader.read_u64()
132    }
133}
134
135impl Serialize for i64 {
136    #[inline]
137    fn serialize(&self, writer: &mut CdrWriter) -> Result<(), SerError> {
138        writer.write_i64(*self)
139    }
140}
141
142impl Deserialize for i64 {
143    #[inline]
144    fn deserialize(reader: &mut CdrReader) -> Result<Self, DeserError> {
145        reader.read_i64()
146    }
147}
148
149// === Floating point ===
150
151impl Serialize for f32 {
152    #[inline]
153    fn serialize(&self, writer: &mut CdrWriter) -> Result<(), SerError> {
154        writer.write_f32(*self)
155    }
156}
157
158impl Deserialize for f32 {
159    #[inline]
160    fn deserialize(reader: &mut CdrReader) -> Result<Self, DeserError> {
161        reader.read_f32()
162    }
163}
164
165impl Serialize for f64 {
166    #[inline]
167    fn serialize(&self, writer: &mut CdrWriter) -> Result<(), SerError> {
168        writer.write_f64(*self)
169    }
170}
171
172impl Deserialize for f64 {
173    #[inline]
174    fn deserialize(reader: &mut CdrReader) -> Result<Self, DeserError> {
175        reader.read_f64()
176    }
177}
178
179// === Character (CDR char is 1 byte) ===
180
181impl Serialize for char {
182    #[inline]
183    fn serialize(&self, writer: &mut CdrWriter) -> Result<(), SerError> {
184        // CDR char is 1 byte, truncate to ASCII
185        writer.write_u8(*self as u8)
186    }
187}
188
189impl Deserialize for char {
190    #[inline]
191    fn deserialize(reader: &mut CdrReader) -> Result<Self, DeserError> {
192        Ok(reader.read_u8()? as char)
193    }
194}
195
196// === String slice (serialization only) ===
197
198impl Serialize for str {
199    #[inline]
200    fn serialize(&self, writer: &mut CdrWriter) -> Result<(), SerError> {
201        writer.write_string(self)
202    }
203}
204
205impl Serialize for &str {
206    #[inline]
207    fn serialize(&self, writer: &mut CdrWriter) -> Result<(), SerError> {
208        writer.write_string(self)
209    }
210}
211
212// === Fixed-size arrays ===
213
214impl<T: Serialize, const N: usize> Serialize for [T; N] {
215    fn serialize(&self, writer: &mut CdrWriter) -> Result<(), SerError> {
216        for item in self.iter() {
217            item.serialize(writer)?;
218        }
219        Ok(())
220    }
221}
222
223impl<T: Deserialize + Default + Copy, const N: usize> Deserialize for [T; N] {
224    fn deserialize(reader: &mut CdrReader) -> Result<Self, DeserError> {
225        let mut arr = [T::default(); N];
226        for item in arr.iter_mut() {
227            *item = T::deserialize(reader)?;
228        }
229        Ok(arr)
230    }
231}
232
233// === heapless::String ===
234
235impl<const N: usize> Serialize for heapless::String<N> {
236    #[inline]
237    fn serialize(&self, writer: &mut CdrWriter) -> Result<(), SerError> {
238        writer.write_string(self.as_str())
239    }
240}
241
242impl<const N: usize> Deserialize for heapless::String<N> {
243    fn deserialize(reader: &mut CdrReader) -> Result<Self, DeserError> {
244        let s = reader.read_string()?;
245        heapless::String::try_from(s).map_err(|_| DeserError::CapacityExceeded)
246    }
247}
248
249// === heapless::Vec ===
250
251impl<T: Serialize, const N: usize> Serialize for heapless::Vec<T, N> {
252    fn serialize(&self, writer: &mut CdrWriter) -> Result<(), SerError> {
253        writer.write_sequence_len(self.len())?;
254        for item in self.iter() {
255            item.serialize(writer)?;
256        }
257        Ok(())
258    }
259}
260
261impl<T: Deserialize, const N: usize> Deserialize for heapless::Vec<T, N> {
262    fn deserialize(reader: &mut CdrReader) -> Result<Self, DeserError> {
263        let len = reader.read_sequence_len()?;
264        if len > N {
265            return Err(DeserError::CapacityExceeded);
266        }
267        let mut vec = heapless::Vec::new();
268        for _ in 0..len {
269            vec.push(T::deserialize(reader)?)
270                .map_err(|_| DeserError::CapacityExceeded)?;
271        }
272        Ok(vec)
273    }
274}
275
276// === alloc types (behind feature flag) ===
277
278#[cfg(feature = "alloc")]
279mod alloc_impl {
280    use super::*;
281    use alloc::{string::String, vec::Vec};
282
283    impl Serialize for String {
284        #[inline]
285        fn serialize(&self, writer: &mut CdrWriter) -> Result<(), SerError> {
286            writer.write_string(self.as_str())
287        }
288    }
289
290    impl Deserialize for String {
291        fn deserialize(reader: &mut CdrReader) -> Result<Self, DeserError> {
292            let s = reader.read_string()?;
293            Ok(String::from(s))
294        }
295    }
296
297    impl<T: Serialize> Serialize for Vec<T> {
298        fn serialize(&self, writer: &mut CdrWriter) -> Result<(), SerError> {
299            writer.write_sequence_len(self.len())?;
300            for item in self.iter() {
301                item.serialize(writer)?;
302            }
303            Ok(())
304        }
305    }
306
307    impl<T: Deserialize> Deserialize for Vec<T> {
308        fn deserialize(reader: &mut CdrReader) -> Result<Self, DeserError> {
309            let len = reader.read_sequence_len()?;
310            let mut vec = Vec::with_capacity(len);
311            for _ in 0..len {
312                vec.push(T::deserialize(reader)?);
313            }
314            Ok(vec)
315        }
316    }
317}
318
319#[cfg(test)]
320mod tests {
321    use super::*;
322
323    #[test]
324    fn test_bool_roundtrip() {
325        let mut buf = [0u8; 16];
326        let mut writer = CdrWriter::new(&mut buf);
327        true.serialize(&mut writer).unwrap();
328        false.serialize(&mut writer).unwrap();
329
330        let mut reader = CdrReader::new(&buf);
331        assert!(bool::deserialize(&mut reader).unwrap());
332        assert!(!bool::deserialize(&mut reader).unwrap());
333    }
334
335    #[test]
336    fn test_integers_roundtrip() {
337        let mut buf = [0u8; 64];
338        let mut writer = CdrWriter::new(&mut buf);
339
340        42u8.serialize(&mut writer).unwrap();
341        (-42i8).serialize(&mut writer).unwrap();
342        1000u16.serialize(&mut writer).unwrap();
343        (-1000i16).serialize(&mut writer).unwrap();
344        100000u32.serialize(&mut writer).unwrap();
345        (-100000i32).serialize(&mut writer).unwrap();
346        10000000000u64.serialize(&mut writer).unwrap();
347        (-10000000000i64).serialize(&mut writer).unwrap();
348
349        let mut reader = CdrReader::new(&buf);
350        assert_eq!(u8::deserialize(&mut reader).unwrap(), 42);
351        assert_eq!(i8::deserialize(&mut reader).unwrap(), -42);
352        assert_eq!(u16::deserialize(&mut reader).unwrap(), 1000);
353        assert_eq!(i16::deserialize(&mut reader).unwrap(), -1000);
354        assert_eq!(u32::deserialize(&mut reader).unwrap(), 100000);
355        assert_eq!(i32::deserialize(&mut reader).unwrap(), -100000);
356        assert_eq!(u64::deserialize(&mut reader).unwrap(), 10000000000);
357        assert_eq!(i64::deserialize(&mut reader).unwrap(), -10000000000);
358    }
359
360    #[test]
361    #[allow(clippy::approx_constant)]
362    fn test_floats_roundtrip() {
363        let mut buf = [0u8; 32];
364        let mut writer = CdrWriter::new(&mut buf);
365
366        3.14f32.serialize(&mut writer).unwrap();
367        2.71828f64.serialize(&mut writer).unwrap();
368
369        let mut reader = CdrReader::new(&buf);
370        assert!((f32::deserialize(&mut reader).unwrap() - 3.14).abs() < 0.001);
371        assert!((f64::deserialize(&mut reader).unwrap() - 2.71828).abs() < 0.00001);
372    }
373
374    #[test]
375    fn test_heapless_string_roundtrip() {
376        let mut buf = [0u8; 32];
377        let mut writer = CdrWriter::new(&mut buf);
378
379        let s: heapless::String<32> = heapless::String::try_from("Hello").unwrap();
380        s.serialize(&mut writer).unwrap();
381
382        let mut reader = CdrReader::new(&buf);
383        let result: heapless::String<32> = Deserialize::deserialize(&mut reader).unwrap();
384        assert_eq!(result.as_str(), "Hello");
385    }
386
387    #[test]
388    fn test_heapless_vec_roundtrip() {
389        let mut buf = [0u8; 64];
390        let mut writer = CdrWriter::new(&mut buf);
391
392        let mut v: heapless::Vec<u32, 8> = heapless::Vec::new();
393        v.push(1).unwrap();
394        v.push(2).unwrap();
395        v.push(3).unwrap();
396        v.serialize(&mut writer).unwrap();
397
398        let mut reader = CdrReader::new(&buf);
399        let result: heapless::Vec<u32, 8> = Deserialize::deserialize(&mut reader).unwrap();
400        assert_eq!(result.as_slice(), &[1, 2, 3]);
401    }
402
403    #[test]
404    fn test_array_roundtrip() {
405        let mut buf = [0u8; 32];
406        let mut writer = CdrWriter::new(&mut buf);
407
408        let arr: [u32; 3] = [10, 20, 30];
409        arr.serialize(&mut writer).unwrap();
410
411        let mut reader = CdrReader::new(&buf);
412        let result: [u32; 3] = Deserialize::deserialize(&mut reader).unwrap();
413        assert_eq!(result, [10, 20, 30]);
414    }
415}