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