Skip to main content

osal_rs/traits/
byte.rs

1/***************************************************************************
2 *
3 * osal-rs
4 * Copyright (C) 2026 Antonio Salsi <passy.linux@zresa.it>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <https://www.gnu.org/licenses/>.
18 *
19 ***************************************************************************/
20
21//! Byte conversion traits for serialization and deserialization.
22//!
23//! This module provides traits for converting types to and from byte arrays,
24//! enabling type-safe serialization for queue and communication operations.
25
26#[cfg(feature = "serde")]
27use osal_rs_serde::Serialize;
28
29#[cfg(not(feature = "serde"))]
30use crate::utils::Result;
31
32/// Trait for types that have a known byte length.
33///
34/// Used to determine the size of data structures when working with byte arrays.
35///
36/// # Examples
37///
38/// ```ignore
39/// use osal_rs::traits::BytesHasLen;
40/// 
41/// let data: [u8; 4] = [1, 2, 3, 4];
42/// assert_eq!(data.len(), 4);
43/// assert!(!data.is_empty());
44/// ```
45pub trait BytesHasLen {
46    /// Returns the length in bytes.
47    ///
48    /// # Returns
49    ///
50    /// Number of bytes in the data structure
51    fn len(&self) -> usize;
52
53    /// Returns `true` if the length is zero.
54    ///
55    /// # Returns
56    ///
57    /// `true` if empty, `false` otherwise
58    fn is_empty(&self) -> bool {
59        self.len() == 0
60    }
61}
62
63/// Automatic implementation of `BytesHasLen` for fixed-size arrays.
64///
65/// This allows arrays of types implementing `Serialize` to automatically
66/// report their size.
67impl<T, const N: usize> BytesHasLen for [T; N] 
68where 
69    T: Serialize + Sized {
70    fn len(&self) -> usize {
71        N
72    }
73}
74
75/// Trait for converting types to byte slices.
76///
77/// Enables serialization of structured data for transmission through
78/// queues or other byte-oriented communication channels.
79///
80/// # Safety
81///
82/// When implementing this trait, ensure that the returned byte slice
83/// is a valid representation of the type and lives at least as long
84/// as the value itself.
85///
86/// # Examples
87///
88/// ```ignore
89/// use osal_rs::traits::Serialize;
90/// 
91/// struct SensorData {
92///     temperature: i16,
93///     humidity: u8,
94/// }
95/// 
96/// impl Serialize for SensorData {
97///     fn to_bytes(&self) -> &[u8] {
98///         // Convert struct to bytes
99///         // Safety: ensure proper memory layout
100///         unsafe {
101///             core::slice::from_raw_parts(
102///                 self as *const Self as *const u8,
103///                 core::mem::size_of::<Self>()
104///             )
105///         }
106///     }
107/// }
108/// ```
109#[cfg(not(feature = "serde"))]
110pub trait Serialize {
111    /// Converts this value to a byte slice.
112    ///
113    /// # Returns
114    ///
115    /// A reference to the byte representation of this value
116    fn to_bytes(&self) -> &[u8];
117}
118
119/// Trait for deserializing types from byte slices.
120///
121/// Enables reconstruction of structured data from byte arrays received
122/// from queues or communication channels.
123///
124/// # Errors
125///
126/// Implementations should return an error if:
127/// - The byte slice is too small or too large
128/// - The data is invalid or corrupted
129/// - The conversion fails for any other reason
130///
131/// # Examples
132///
133/// ```ignore
134/// use osal_rs::traits::Deserialize;
135/// use osal_rs::utils::Result;
136/// 
137/// struct SensorData {
138///     temperature: i16,
139///     humidity: u8,
140/// }
141/// 
142/// impl Deserialize for SensorData {
143///     fn from_bytes(bytes: &[u8]) -> Result<Self> {
144///         if bytes.len() < 3 {
145///             return Err(Error::InvalidParameter);
146///         }
147///         Ok(SensorData {
148///             temperature: i16::from_le_bytes([bytes[0], bytes[1]]),
149///             humidity: bytes[2],
150///         })
151///     }
152/// }
153/// ```
154#[cfg(not(feature = "serde"))]
155pub trait Deserialize: Sized
156where
157    Self: Sized {
158    /// Creates a new instance from a byte slice.
159    ///
160    /// # Parameters
161    ///
162    /// * `bytes` - The byte slice to deserialize from
163    ///
164    /// # Returns
165    ///
166    /// * `Ok(Self)` - Successfully deserialized value
167    /// * `Err(Error)` - Deserialization failed (invalid data, wrong size, etc.)
168    fn from_bytes(bytes: &[u8]) -> Result<Self>;
169}
170
171
172