rsomeip_bytes/
ser.rs

1//! Serialization according to the SOME/IP protocol.
2//!
3//! Provides the [`Serialize`] and [`SerializeString`] traits for serializing data, and several
4//! implementations of these traits for types of the standard library.
5
6use super::{BufMut, Bytes, BytesMut, LengthField};
7
8/// Serialize data into a SOME/IP byte stream.
9///
10/// This trait provides methods for serializing data structures into a byte stream ([`BufMut`])
11/// encoded in the SOME/IP on-wire format.
12///
13/// [`serialize`] is used to serialize statically sized types, while [`serialize_len`] is used to
14/// serialize dynamically sized types into the stream.
15///
16/// [`serialize`]: Serialize::serialize
17/// [`serialize_len`]: Serialize::serialize_len
18pub trait Serialize {
19    /// Serializes the implementing type into the buffer.
20    ///
21    /// Returns the size of the serialized data.
22    ///
23    /// # Errors
24    ///
25    /// This function will return an error if serialization fails for any reason, such as the
26    /// buffer not having enough space.
27    ///
28    /// # Examples
29    ///
30    /// ```rust
31    /// use rsomeip_bytes::{BytesMut, Serialize};
32    /// let mut buffer = BytesMut::with_capacity(3);
33    /// assert_eq!(1u8.serialize(&mut buffer), Ok(1));
34    /// assert_eq!(2u16.serialize(&mut buffer), Ok(2));
35    /// assert_eq!(&buffer.freeze()[..], &[1u8, 0u8, 2u8][..]);
36    /// ```
37    fn serialize(&self, buffer: &mut impl BufMut) -> Result<usize, SerializeError>;
38
39    /// Serializes the implementing type into the buffer.
40    ///
41    /// This method specifies a length field which is used to indicate the size of the data to be
42    /// serialized. This is necessary in case of dynamically sized data structures, like [`Vec`].
43    ///
44    /// Returns the size of the serialized data including the length field.
45    ///
46    /// # Errors
47    ///
48    /// This function will return an error if serialization fails for any reason, such as the
49    /// buffer not having enough space, or the length of the serialized data exceeding the capacity
50    /// of the length field.
51    ///
52    /// # Examples
53    ///
54    /// ```rust
55    /// use rsomeip_bytes::{BytesMut, Serialize, LengthField};
56    /// let mut buffer = BytesMut::with_capacity(3);
57    /// let vec = vec![0u8, 1u8];
58    /// assert_eq!(vec.serialize_len(LengthField::U8, &mut buffer), Ok(3));
59    /// assert_eq!(&buffer.freeze()[..], &[2u8, 0u8, 1u8][..]);
60    /// ```
61    fn serialize_len(
62        &self,
63        length: LengthField,
64        buffer: &mut impl BufMut,
65    ) -> Result<usize, SerializeError> {
66        let mut size = match length {
67            LengthField::U8 => u8::try_from(self.size_hint())
68                .map_err(|_| SerializeError::InvalidLength {
69                    required: self.size_hint(),
70                    maximum: u8::MAX as usize,
71                })?
72                .serialize(buffer)?,
73            LengthField::U16 => u16::try_from(self.size_hint())
74                .map_err(|_| SerializeError::InvalidLength {
75                    required: self.size_hint(),
76                    maximum: u16::MAX as usize,
77                })?
78                .serialize(buffer)?,
79            LengthField::U32 => u32::try_from(self.size_hint())
80                .map_err(|_| SerializeError::InvalidLength {
81                    required: self.size_hint(),
82                    maximum: u32::MAX as usize,
83                })?
84                .serialize(buffer)?,
85        };
86        size += self.serialize(buffer)?;
87        Ok(size)
88    }
89
90    /// Returns the expected length of the serialized data.
91    ///
92    /// When using [`serialize_len`], the length field is serialized before the type itself.
93    ///
94    /// This method serves as way to calculate the length of the serialized type before serializing it.
95    ///
96    /// # Examples
97    ///
98    /// ```rust
99    /// use rsomeip_bytes::Serialize;
100    ///
101    /// assert_eq!(0u8.size_hint(), 1);
102    /// assert_eq!(0u32.size_hint(), 4);
103    /// assert_eq!(vec![1u8, 2, 3].size_hint(), 3);
104    /// ```
105    ///
106    /// [`serialize_len`]: Serialize::serialize_len
107    fn size_hint(&self) -> usize;
108}
109
110macro_rules! serialize_basic_type {
111    ($t:ty, $f:ident) => {
112        impl Serialize for $t {
113            fn serialize(&self, buffer: &mut impl BufMut) -> Result<usize, SerializeError> {
114                BufMut::$f(buffer, *self);
115                Ok(size_of::<$t>())
116            }
117
118            fn size_hint(&self) -> usize {
119                size_of::<$t>()
120            }
121        }
122    };
123}
124
125serialize_basic_type!(u8, put_u8);
126serialize_basic_type!(u16, put_u16);
127serialize_basic_type!(u32, put_u32);
128serialize_basic_type!(u64, put_u64);
129serialize_basic_type!(i8, put_i8);
130serialize_basic_type!(i16, put_i16);
131serialize_basic_type!(i32, put_i32);
132serialize_basic_type!(i64, put_i64);
133serialize_basic_type!(f32, put_f32);
134serialize_basic_type!(f64, put_f64);
135
136impl Serialize for bool {
137    fn serialize(&self, buffer: &mut impl BufMut) -> Result<usize, SerializeError> {
138        if *self {
139            1u8.serialize(buffer)
140        } else {
141            0u8.serialize(buffer)
142        }
143    }
144
145    fn size_hint(&self) -> usize {
146        size_of::<u8>()
147    }
148}
149
150impl<T> Serialize for &T
151where
152    T: Serialize,
153{
154    fn serialize(&self, buffer: &mut impl BufMut) -> Result<usize, SerializeError> {
155        (*self).serialize(buffer)
156    }
157
158    fn size_hint(&self) -> usize {
159        (*self).size_hint()
160    }
161}
162
163impl<T> Serialize for &[T]
164where
165    T: Serialize,
166{
167    fn serialize(&self, buffer: &mut impl BufMut) -> Result<usize, SerializeError> {
168        let mut total = 0;
169        for element in *self {
170            total += element.serialize(buffer)?;
171        }
172        Ok(total)
173    }
174
175    fn size_hint(&self) -> usize {
176        let mut total = 0;
177        for element in *self {
178            total += element.size_hint();
179        }
180        total
181    }
182}
183
184impl<T> Serialize for Vec<T>
185where
186    T: Serialize,
187{
188    fn serialize(&self, buffer: &mut impl BufMut) -> Result<usize, SerializeError> {
189        self.as_slice().serialize(buffer)
190    }
191
192    fn size_hint(&self) -> usize {
193        self.as_slice().size_hint()
194    }
195}
196
197impl<T, const N: usize> Serialize for [T; N]
198where
199    T: Serialize,
200{
201    fn serialize(&self, buffer: &mut impl BufMut) -> Result<usize, SerializeError> {
202        self.as_slice().serialize(buffer)
203    }
204
205    fn size_hint(&self) -> usize {
206        self.as_slice().size_hint()
207    }
208}
209
210macro_rules! serialize_tuple {
211    ( $( $name:ident )+ ) => {
212        impl<$($name: Serialize),+> Serialize for ($($name,)+)
213        {
214            #[allow(non_snake_case)]
215            fn serialize(&self, buffer: &mut impl BufMut) -> Result<usize, SerializeError> {
216                let ($($name,)+) = self;
217                let mut total = 0;
218                $(total += $name.serialize(buffer)?;)+
219                Ok(total)
220            }
221
222            #[allow(non_snake_case)]
223            fn size_hint(&self) -> usize {
224                let ($($name,)+) = self;
225                let mut total = 0;
226                $(total += $name.size_hint();)+
227                total
228            }
229        }
230    };
231}
232
233serialize_tuple! { A }
234serialize_tuple! { A B }
235serialize_tuple! { A B C }
236serialize_tuple! { A B C D }
237serialize_tuple! { A B C D E }
238serialize_tuple! { A B C D E F }
239serialize_tuple! { A B C D E F G }
240serialize_tuple! { A B C D E F G H }
241serialize_tuple! { A B C D E F G H I }
242serialize_tuple! { A B C D E F G H I J }
243serialize_tuple! { A B C D E F G H I J K }
244serialize_tuple! { A B C D E F G H I J K L }
245
246impl Serialize for Bytes {
247    fn serialize(&self, buffer: &mut impl BufMut) -> Result<usize, SerializeError> {
248        buffer.put_slice(self);
249        Ok(self.len())
250    }
251
252    fn size_hint(&self) -> usize {
253        self.len()
254    }
255}
256
257/// Serialize strings of various encodings into a SOME/IP byte stream.
258///
259/// The protocol specifies three encodings (UTF-8, UTF-16 Little-Endian, and UTF-16 Big-Endian)
260/// which require adding Byte-Order-Marks and Delimiters to the start and end of the data stream,
261/// respectively.
262///
263/// This trait provides one method for serializing strings using each of those encodings.
264pub trait SerializeString {
265    /// Serializes the string into the buffer using UTF-8 encoding.
266    ///
267    /// A length field can be specified to indicate the size of the serialized data.
268    ///
269    /// # Errors
270    ///
271    /// This function will return an error if serialization fails for any reason, such as the
272    /// buffer not having enough space, or the length of the serialized data exceeding the capacity
273    /// of the length field.
274    ///
275    /// # Examples
276    ///
277    /// ```rust
278    /// use rsomeip_bytes::{SerializeString, BytesMut};
279    /// let mut buffer = BytesMut::with_capacity(10);
280    /// assert_eq!("Hello!".serialize_utf8(&mut buffer, None), Ok(10));
281    /// assert_eq!(
282    ///     &buffer.freeze()[..],
283    ///     [
284    ///         0xef_u8, 0xbb, 0xbf, // UTF-8 Byte Order Mark
285    ///         0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21, // Hello!
286    ///         0x00  // Delimiter
287    ///     ]
288    /// );
289    /// ```
290    fn serialize_utf8(
291        &self,
292        buffer: &mut BytesMut,
293        len: Option<LengthField>,
294    ) -> Result<usize, SerializeError>;
295
296    /// Serializes the string into the buffer using UTF-16 Big-Endian encoding.
297    ///
298    /// A length field can be specified to indicate the size of the serialized data.
299    ///
300    /// # Errors
301    ///
302    /// This function will return an error if serialization fails for any reason, such as the
303    /// buffer not having enough space, or the length of the serialized data exceeding the capacity
304    /// of the length field.
305    ///
306    /// # Examples
307    ///
308    /// ```rust
309    /// use rsomeip_bytes::{SerializeString, BytesMut};
310    /// let mut buffer = BytesMut::with_capacity(12);
311    /// assert_eq!("语言处理".serialize_utf16_be(&mut buffer, None), Ok(12));
312    /// assert_eq!(
313    ///     &buffer.freeze()[..],
314    ///     [
315    ///         0xfe_u8, 0xff, // UTF-16 Big Endian Byte Order Mark
316    ///         0x8b, 0xed, 0x8a, 0x00, 0x59, 0x04, 0x74, 0x06, // 语言处理
317    ///         0x00, 0x00, // Delimiter
318    ///     ]
319    /// );
320    /// ```
321    fn serialize_utf16_be(
322        &self,
323        buffer: &mut BytesMut,
324        len: Option<LengthField>,
325    ) -> Result<usize, SerializeError>;
326
327    /// Serializes the string into the buffer using UTF-16 Little-Endian encoding.
328    ///
329    /// A length field can be specified to indicate the size of the serialized data.
330    ///
331    /// # Errors
332    ///
333    /// This function will return an error if serialization fails for any reason, such as the
334    /// buffer not having enough space, or the length of the serialized data exceeding the capacity
335    /// of the length field.
336    ///
337    /// # Examples
338    ///
339    /// ```rust
340    /// use rsomeip_bytes::{SerializeString, BytesMut};
341    /// let mut buffer = BytesMut::with_capacity(12);
342    /// assert_eq!("语言处理".serialize_utf16_le(&mut buffer, None), Ok(12));
343    /// assert_eq!(
344    ///     &buffer.freeze()[..],
345    ///     [
346    ///         0xff_u8, 0xfe, // UTF-16 Little Endian Byte Order Mark
347    ///         0xed, 0x8b, 0x00, 0x8a, 0x04, 0x59, 0x06, 0x74, // 语言处理
348    ///         0x00, 0x00, // Delimiter
349    ///     ]
350    /// );
351    /// ```
352    fn serialize_utf16_le(
353        &self,
354        buffer: &mut BytesMut,
355        len: Option<LengthField>,
356    ) -> Result<usize, SerializeError>;
357}
358
359impl SerializeString for &str {
360    fn serialize_utf8(
361        &self,
362        buffer: &mut BytesMut,
363        len: Option<LengthField>,
364    ) -> Result<usize, SerializeError> {
365        let data = (
366            [0xef_u8, 0xbb, 0xbf], // Byte Order Mark.
367            self.as_bytes(),
368            0x00_u8, // Delimiter.
369        );
370        match len {
371            Some(len) => data.serialize_len(len, buffer),
372            None => data.serialize(buffer),
373        }
374    }
375
376    fn serialize_utf16_be(
377        &self,
378        buffer: &mut BytesMut,
379        length: Option<LengthField>,
380    ) -> Result<usize, SerializeError> {
381        let string = Utf16String {
382            inner: self,
383            endianness: Endianness::Big,
384        };
385        match length {
386            Some(length) => string.serialize_len(length, buffer),
387            None => string.serialize(buffer),
388        }
389    }
390
391    fn serialize_utf16_le(
392        &self,
393        buffer: &mut BytesMut,
394        length: Option<LengthField>,
395    ) -> Result<usize, SerializeError> {
396        let string = Utf16String {
397            inner: self,
398            endianness: Endianness::Little,
399        };
400        match length {
401            Some(length) => string.serialize_len(length, buffer),
402            None => string.serialize(buffer),
403        }
404    }
405}
406
407/// A wrapper for serializing UTF-16 strings.
408#[derive(Debug)]
409struct Utf16String<'a> {
410    inner: &'a str,
411    endianness: Endianness,
412}
413
414impl Serialize for Utf16String<'_> {
415    fn serialize(&self, buffer: &mut impl BufMut) -> Result<usize, SerializeError> {
416        let mut size = 0;
417        match self.endianness {
418            Endianness::Little => {
419                size += 0xfffe_u16.serialize(buffer)?; // Byte Order Mark.
420                for value in self.inner.encode_utf16() {
421                    size += value.to_le_bytes().serialize(buffer)?;
422                }
423            }
424            Endianness::Big => {
425                size += 0xfeff_u16.serialize(buffer)?; // Byte Order Mark.
426                for value in self.inner.encode_utf16() {
427                    size += value.to_be_bytes().serialize(buffer)?;
428                }
429            }
430        }
431        size += 0x0000_u16.serialize(buffer)?; // Delimiter.
432        Ok(size)
433    }
434
435    fn size_hint(&self) -> usize {
436        let mut size = size_of::<u16>() * 2; // Byte Order Mark + Delimiter.
437        for _ in self.inner.encode_utf16() {
438            size += size_of::<u16>();
439        }
440        size
441    }
442}
443
444#[derive(Debug, Clone, Copy, PartialEq, Eq)]
445enum Endianness {
446    Little,
447    Big,
448}
449
450/// Represents an error during the serialization process.
451#[derive(Debug, PartialEq, Eq, thiserror::Error)]
452#[non_exhaustive]
453pub enum SerializeError {
454    /// The length of the serialized type does not fit inside the length field.
455    #[error("length exceeds capacity of length field: {required} vs {maximum}")]
456    InvalidLength { required: usize, maximum: usize },
457    /// Some other error has occurred.
458    #[error("{0}")]
459    Other(String),
460}
461
462#[cfg(test)]
463mod tests {
464    use super::*;
465
466    macro_rules! test_serialize_basic_type {
467        ($t:ty, $name:ident) => {
468            #[test]
469            fn $name() {
470                let mut buffer = BytesMut::with_capacity(size_of::<$t>());
471                let result = <$t>::MAX.serialize(&mut buffer);
472                assert_eq!(result, Ok(size_of::<$t>()));
473                assert_eq!(result, Ok(<$t>::MAX.size_hint()));
474                assert_eq!(&buffer.freeze()[..], <$t>::MAX.to_be_bytes());
475            }
476        };
477    }
478
479    test_serialize_basic_type!(u8, serialize_u8);
480    test_serialize_basic_type!(u16, serialize_u16);
481    test_serialize_basic_type!(u32, serialize_u32);
482    test_serialize_basic_type!(u64, serialize_u64);
483    test_serialize_basic_type!(i8, serialize_i8);
484    test_serialize_basic_type!(i16, serialize_i16);
485    test_serialize_basic_type!(i32, serialize_i32);
486    test_serialize_basic_type!(i64, serialize_i64);
487    test_serialize_basic_type!(f32, serialize_f32);
488    test_serialize_basic_type!(f64, serialize_f64);
489
490    #[test]
491    fn serialize_bool() {
492        let mut buffer = BytesMut::with_capacity(1);
493        let size = true
494            .serialize(&mut buffer)
495            .expect("should serialize the bool");
496        assert_eq!(size, 1);
497        assert_eq!(true.size_hint(), 1);
498        assert_eq!(&buffer.freeze()[..], &[1u8]);
499    }
500
501    #[test]
502    fn serialize_len() {
503        let mut buffer = BytesMut::with_capacity(3);
504        let vec = vec![0u8, 1u8];
505        assert_eq!(vec.serialize_len(LengthField::U8, &mut buffer), Ok(3));
506        assert_eq!(&buffer.freeze()[..], &[2u8, 0u8, 1u8][..]);
507    }
508
509    #[test]
510    fn serialize_vec() {
511        let mut buffer = BytesMut::with_capacity(2);
512        let vec = vec![1u8, 2u8];
513        let size = vec
514            .serialize(&mut buffer)
515            .expect("should serialize the vec");
516        assert_eq!(size, 2);
517        assert_eq!(size, vec.size_hint());
518        assert_eq!(&buffer.freeze()[..], &[1u8, 2u8][..]);
519    }
520
521    #[test]
522    fn serialize_array() {
523        let mut buffer = BytesMut::with_capacity(2);
524        let array = [1u8, 2u8];
525        let size = array
526            .serialize(&mut buffer)
527            .expect("should serialize the array");
528        assert_eq!(size, 2);
529        assert_eq!(size, array.size_hint());
530        assert_eq!(&buffer.freeze()[..], &[1u8, 2u8][..]);
531    }
532
533    #[test]
534    fn serialize_tuple() {
535        let mut buffer = BytesMut::with_capacity(2);
536        let tuple = (1u8, 2u8);
537        let size = tuple
538            .serialize(&mut buffer)
539            .expect("should serialize the tuple");
540        assert_eq!(size, 2);
541        assert_eq!(size, tuple.size_hint());
542        assert_eq!(&buffer.freeze()[..], &[1u8, 2u8][..]);
543    }
544
545    #[test]
546    fn serialize_bytes() {
547        let mut buffer = BytesMut::with_capacity(2);
548        let bytes = Bytes::copy_from_slice(&[1u8, 2u8]);
549        let size = bytes
550            .serialize(&mut buffer)
551            .expect("should serialize the buffer");
552        assert_eq!(size, 2);
553        assert_eq!(size, bytes.size_hint());
554        assert_eq!(&buffer.freeze()[..], &[1u8, 2u8][..]);
555    }
556
557    #[test]
558    fn serialize_utf8() {
559        let mut buffer = BytesMut::with_capacity(10);
560        let size = "Hello!"
561            .serialize_utf8(&mut buffer, None)
562            .expect("should serialize the string");
563        assert_eq!(size, 10);
564        assert_eq!(
565            &buffer.freeze()[..],
566            [
567                0xef_u8, 0xbb, 0xbf, // UTF-8 Byte Order Mark
568                0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21, // Hello!
569                0x00  // Delimiter
570            ]
571        );
572    }
573
574    #[test]
575    fn serialize_utf16_be() {
576        let mut buffer = BytesMut::with_capacity(12);
577        let size = "语言处理"
578            .serialize_utf16_be(&mut buffer, None)
579            .expect("should serialize the string");
580        assert_eq!(size, 12);
581        assert_eq!(
582            &buffer.freeze()[..],
583            [
584                0xfe_u8, 0xff, // UTF-16 Big Endian Byte Order Mark
585                0x8b, 0xed, 0x8a, 0x00, 0x59, 0x04, 0x74, 0x06, // 语言处理
586                0x00, 0x00, // Delimiter
587            ]
588        );
589    }
590
591    #[test]
592    fn serialize_utf16_le() {
593        let mut buffer = BytesMut::with_capacity(12);
594        let size = "语言处理"
595            .serialize_utf16_le(&mut buffer, None)
596            .expect("should serialize the string");
597        assert_eq!(size, 12);
598        assert_eq!(
599            &buffer.freeze()[..],
600            [
601                0xff_u8, 0xfe, // UTF-16 Little Endian Byte Order Mark
602                0xed, 0x8b, 0x00, 0x8a, 0x04, 0x59, 0x06, 0x74, // 语言处理
603                0x00, 0x00, // Delimiter
604            ]
605        );
606    }
607}