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