Skip to main content

ace_core/
iter.rs

1use core::marker::PhantomData;
2
3use crate::{
4    codec::{FrameRead, FrameWrite, Writer},
5    DiagError,
6};
7
8// region: FrameIter
9
10/// A lazy iterator that decodes elements of type `T` from a byte slice.
11///
12/// Provides a zero-copy, no_std safe way to iterate over a repeated sequence
13/// of `T` values encoded contiguously in a buffer. Each call to `next()`
14/// advances the internal cursor by however many bytes `T::decode` consumes.
15///
16/// The caller is responsible for slicing the correct byte range before
17/// constructing `FrameIter` - it does not advance a parent cursor itself.
18/// This allows callers to control exactly which bytes are in scope, including
19/// cases where element stride must be computed from prior fields.
20///
21/// # Example - macro generated field
22///
23/// ```ignore
24/// # use ace_core::FrameIter;
25///
26/// #[derive(FrameRead)]
27/// #[frame(error = "UdsError")]
28/// pub struct DefineByIdentifierRequest<'a> {
29///     pub dynamically_defined_data_identifier: u16,
30///     pub source_data: FrameIter<'a, SourceData>,
31/// }
32///
33/// #[derive(FrameRead)]
34/// #[frame(error = "UdsError")]
35/// pub struct SourceData {
36///     pub field_1: u16,
37///     pub field_2: [u8; 2],
38/// }
39/// ```
40///
41/// # Example - manual impl with computed stride
42///
43/// ```ignore
44/// # use ace_core::FrameIter;
45/// impl<'a> FrameRead<'a> for DefineByMemoryAddressRequest<'a> {
46///     type Error = UdsError;
47///
48///     fn decode(buf: &mut &'a [u8]) -> Result<Self, Self::Error> {
49///         let address_and_length_format_identifier = u8::decode(buf)?;
50///         let memory_address_length = (address_and_length_format_identifier & 0x0F) as usize;
51///         let memory_size_length    = (address_and_length_format_identifier >> 4)   as usize;
52///         let stride = memory_address_length + memory_size_length;
53///         let data_len = (buf.len() / stride) * stride;
54///         let memory_data = FrameIter::new(&buf[..data_len]);
55///         *buf = &buf[data_len..];
56///         Ok(Self { address_and_length_format_identifier, memory_data })
57///     }
58/// }
59/// ```
60#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug)]
61pub struct FrameIter<'a, T> {
62    buf: &'a [u8],
63    _marker: PhantomData<T>,
64}
65
66impl<'a, T> FrameIter<'a, T> {
67    /// Constructs a `FrameIter` over the given byte slice.
68    ///
69    /// The caller controls which bytes are passed in - this does not
70    /// advance any parent cursor.
71    #[must_use]
72    pub fn new(buf: &'a [u8]) -> Self {
73        Self {
74            buf,
75            _marker: PhantomData,
76        }
77    }
78
79    /// Returns the number of undecoded bytes remaining.
80    #[inline]
81    #[must_use]
82    pub fn remaining(&self) -> usize {
83        self.buf.len()
84    }
85
86    /// Returns `true` if no bytes remain to be decoded.
87    #[inline]
88    #[must_use]
89    pub fn is_exhausted(&self) -> bool {
90        self.buf.is_empty()
91    }
92
93    /// Returns the raw undecoded bytes.
94    #[inline]
95    #[must_use]
96    pub fn as_slice(&self) -> &'a [u8] {
97        self.buf
98    }
99}
100
101// endregion: FrameIter
102
103// region: Iterator impl
104
105impl<'a, T> Iterator for FrameIter<'a, T>
106where
107    T: FrameRead<'a>,
108{
109    type Item = Result<T, T::Error>;
110
111    fn next(&mut self) -> Option<Self::Item> {
112        if self.buf.is_empty() {
113            return None;
114        }
115        let mut tmp = self.buf;
116        match T::decode(&mut tmp) {
117            Ok(value) => {
118                self.buf = tmp;
119                Some(Ok(value))
120            }
121            Err(e) => {
122                // Poison the buffer on error - further iteration is undefined
123                self.buf = &[];
124                Some(Err(e))
125            }
126        }
127    }
128}
129
130// endregion: Iterator impl
131
132// region: FrameRead impl
133
134/// `FrameIter` implements `FrameRead` for use as a trailing field in
135/// derived structs. Consumes all remaining bytes from the cursor.
136impl<'a, T> FrameRead<'a> for FrameIter<'a, T>
137where
138    T: FrameRead<'a>,
139{
140    type Error = T::Error;
141
142    fn decode(buf: &mut &'a [u8]) -> Result<Self, Self::Error> {
143        let slice = *buf;
144        *buf = &buf[buf.len()..];
145        Ok(Self::new(slice))
146    }
147}
148
149// endregion: FrameRead impl
150
151// region: FrameWrite impl
152
153/// Encodes by writing the raw underlying bytes directly.
154///
155/// `FrameIter` stores the original encoded bytes verbatim - encoding simply
156/// copies them out. No re-decode/re-encode cycle is needed or performed.
157/// No bounds on `T` required since the bytes are written as-is.
158impl<'a, T> FrameWrite for FrameIter<'a, T> {
159    type Error = DiagError;
160
161    fn encode<W: Writer>(&self, buf: &mut W) -> Result<(), Self::Error> {
162        buf.write_bytes(self.as_slice())
163    }
164}
165
166// endregion: FrameWrite impl