1use crate::{encoding, error, item_encoding, list};
3use core::marker;
4use core::{fmt, slice};
5
6#[repr(transparent)]
10pub struct Repeated<'a, A, E>(list::List<'a, A>, marker::PhantomData<E>)
11where
12 E: item_encoding::ItemEncoding<'a, A>;
13
14#[derive(Clone, Debug, Default)]
16pub struct Iter<'a, A, E>(IterRepr<'a, A, E>)
17where
18 E: item_encoding::ItemEncoding<'a, A>;
19
20#[derive(Clone, Debug, Default)]
21enum IterRepr<'a, A, E>
22where
23 E: item_encoding::ItemEncoding<'a, A>,
24{
25 #[default]
26 Empty,
27 MessageBuffer {
28 msg_buf: list::MessageBuffer<'a>,
29 phantom: marker::PhantomData<E>,
30 },
31 Slice(slice::Iter<'a, A>),
32}
33
34impl<'a, A, E> Repeated<'a, A, E>
35where
36 E: item_encoding::ItemEncoding<'a, A>,
37{
38 pub const fn empty() -> Self {
40 Self(list::List::empty(), marker::PhantomData)
41 }
42
43 pub const fn from_slice(slice: &'a [A]) -> Self {
47 Self(list::List::from_slice(slice), marker::PhantomData)
48 }
49
50 pub const fn from_msg_buf(tag: u32, data: &'a [u8]) -> Self {
52 Self(list::List::from_msg_buf(tag, data), marker::PhantomData)
53 }
54
55 pub(crate) fn is_unpopulated(&self) -> bool {
61 matches!(self.0, list::List::Empty)
62 }
63}
64
65impl<'a, A, E> Repeated<'a, A, E>
66where
67 A: Clone,
68 E: item_encoding::ItemEncoding<'a, A>,
69{
70 pub fn iter(&self) -> Iter<'a, A, E> {
71 self.into_iter()
72 }
73
74 pub fn is_empty(&self) -> bool {
75 self.iter().next().is_none() }
80
81 pub fn len(&self) -> usize {
82 self.iter().count() }
84}
85
86impl<'a, A, E> Iter<'a, A, E>
87where
88 E: item_encoding::ItemEncoding<'a, A>,
89{
90 fn from_list(lst: list::List<'a, A>) -> Self {
91 let repr = match lst {
92 list::List::Empty => IterRepr::Empty,
93 list::List::MessageBuffer(msg_buf) => IterRepr::MessageBuffer {
94 msg_buf,
95 phantom: marker::PhantomData,
96 },
97 list::List::Slice(slice) => IterRepr::Slice(slice.into_iter()),
98 };
99 Self(repr)
100 }
101}
102
103impl<'a, A, E> PartialEq for Repeated<'a, A, E>
104where
105 A: Clone + PartialEq,
106 E: item_encoding::ItemEncoding<'a, A>,
107{
108 fn eq(&self, other: &Self) -> bool {
109 self.iter().eq(other.iter())
110 }
111}
112
113impl<'a, A, E> Clone for Repeated<'a, A, E>
114where
115 E: item_encoding::ItemEncoding<'a, A>,
116{
117 fn clone(&self) -> Self {
118 Repeated(self.0, self.1)
119 }
120}
121
122impl<'a, A, E> Copy for Repeated<'a, A, E> where E: item_encoding::ItemEncoding<'a, A> {}
123
124impl<'a, A, E> Default for Repeated<'a, A, E>
125where
126 E: item_encoding::ItemEncoding<'a, A>,
127{
128 fn default() -> Self {
129 Self::empty()
130 }
131}
132
133impl<'a, A, E> fmt::Debug for Repeated<'a, A, E>
134where
135 A: Clone + fmt::Debug,
136 E: item_encoding::ItemEncoding<'a, A>,
137{
138 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
139 let mut list_fmt = f.debug_list();
140 for ref item in self.iter() {
141 list_fmt.entry(item);
142 }
143 list_fmt.finish()
144 }
145}
146
147#[cfg(feature = "defmt")]
148impl<'a, A, E> defmt::Format for Repeated<'a, A, E>
149where
150 A: Clone + defmt::Format,
151 E: item_encoding::ItemEncoding<'a, A>,
152{
153 fn format(&self, fmt: defmt::Formatter) {
154 defmt::write!(fmt, "[");
155 for ref item in self.iter() {
156 match item {
157 Ok(item) => {
158 defmt::write!(fmt, "{:?}", item);
159 }
160 Err(e) => {
161 defmt::write!(fmt, "...error: {:?}", e);
162 break;
163 }
164 }
165 }
166 defmt::write!(fmt, "]");
167 }
168}
169
170impl<'a, A, E> IntoIterator for Repeated<'a, A, E>
171where
172 A: Clone,
173 E: item_encoding::ItemEncoding<'a, A>,
174{
175 type Item = Result<A, error::DecodeError>;
176 type IntoIter = Iter<'a, A, E>;
177
178 fn into_iter(self) -> Self::IntoIter {
179 Iter::from_list(self.0)
180 }
181}
182
183impl<'a, 'b, A, E> IntoIterator for &'b Repeated<'a, A, E>
184where
185 A: Clone,
186 E: item_encoding::ItemEncoding<'a, A>,
187{
188 type Item = Result<A, error::DecodeError>;
189 type IntoIter = Iter<'a, A, E>;
190
191 fn into_iter(self) -> Self::IntoIter {
192 Iter::from_list(self.0)
193 }
194}
195
196impl<'a, A, E> Iterator for Iter<'a, A, E>
197where
198 A: Clone,
199 E: item_encoding::ItemEncoding<'a, A>,
200{
201 type Item = Result<A, error::DecodeError>;
202
203 #[cfg_attr(feature = "assert-no-panic", no_panic::no_panic)]
204 fn next(&mut self) -> Option<Self::Item> {
205 match self.0 {
206 IterRepr::Empty => None,
207 IterRepr::MessageBuffer {
208 ref mut msg_buf,
209 phantom: _,
210 } => {
211 let result = next_item::<A, E>(msg_buf);
212 if result.is_err() {
213 self.0 = IterRepr::Empty;
215 }
216 result.transpose()
217 }
218 IterRepr::Slice(ref mut iter) => iter.next().cloned().map(|v| Ok(v)),
219 }
220 }
221}
222
223impl<'a, A, E> From<&'a [A]> for Repeated<'a, A, E>
224where
225 E: item_encoding::ItemEncoding<'a, A>,
226{
227 fn from(value: &'a [A]) -> Self {
228 Self::from_slice(value)
229 }
230}
231
232#[cfg_attr(feature = "assert-no-panic", no_panic::no_panic)]
233fn next_item<'a, A, E>(
234 msg_buf: &mut list::MessageBuffer<'a>,
235) -> Result<Option<A>, error::DecodeError>
236where
237 A: 'a,
238 E: item_encoding::ItemEncoding<'a, A>,
239{
240 let cursor = &mut msg_buf.data;
241 while !cursor.is_empty() {
242 let (tag, wire_type) = encoding::decode_key(cursor)?;
243 if tag == msg_buf.tag {
244 if wire_type == E::WIRE_TYPE {
247 return Ok(Some(E::decode_single_value(cursor)?));
249 } else {
250 return Err(error::DecodeError::UnexpectedWireTypeValue {
251 actual: wire_type,
252 expected: E::WIRE_TYPE,
253 });
254 }
255 } else {
256 encoding::skip_field(wire_type, tag, cursor)?;
257 }
258 }
259 Ok(None)
261}