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