1use crate::Message;
2
3struct MessagesIter<'a, 'b> {
5 messages: &'b [Option<Message<'a>>],
6 count: usize,
7 pos: usize,
8}
9
10impl<'a, 'b> Iterator for MessagesIter<'a, 'b> {
11 type Item = &'b Message<'a>;
12
13 #[inline]
14 fn next(&mut self) -> Option<Self::Item> {
15 while self.pos < self.count {
16 let result = self.messages[self.pos].as_ref();
17 self.pos += 1;
18 if let Some(msg) = result {
19 return Some(msg);
20 }
21 }
22 None
23 }
24}
25
26include!(concat!(env!("OUT_DIR"), "/limits.rs"));
37
38#[derive(Debug, Clone, PartialEq, Eq, Hash)]
44pub struct Messages<'a> {
45 #[cfg(not(any(feature = "alloc", feature = "kernel")))]
46 messages: [Option<Message<'a>>; MAX_MESSAGES],
47 #[cfg(any(feature = "alloc", feature = "kernel"))]
48 messages: alloc::boxed::Box<[Option<Message<'a>>]>,
49 message_count: usize,
50}
51
52impl<'a> Messages<'a> {
53 #[allow(dead_code)] pub(crate) fn from_messages_slice(messages: &[Message<'a>]) -> Self {
56 let count = messages.len().min(MAX_MESSAGES);
57
58 #[cfg(not(any(feature = "alloc", feature = "kernel")))]
59 {
60 let mut messages_array: [Option<Message<'a>>; MAX_MESSAGES] =
61 [const { None }; MAX_MESSAGES];
62 for (i, message) in messages.iter().take(MAX_MESSAGES).enumerate() {
63 messages_array[i] = Some(message.clone());
64 }
65 Self {
66 messages: messages_array,
67 message_count: count,
68 }
69 }
70
71 #[cfg(any(feature = "alloc", feature = "kernel"))]
72 {
73 use crate::compat::vec_with_capacity;
74 use alloc::vec::Vec;
75 let mut messages_vec: Vec<Option<Message<'a>>> = vec_with_capacity(count);
76 for message in messages.iter().take(count) {
77 messages_vec.push(Some(message.clone()));
78 }
79 Self {
80 messages: messages_vec.into_boxed_slice(),
81 message_count: count,
82 }
83 }
84 }
85
86 pub(crate) fn from_options_slice(
88 messages: &[Option<Message<'a>>],
89 message_count: usize,
90 ) -> Self {
91 let count = message_count.min(MAX_MESSAGES).min(messages.len());
92
93 #[cfg(not(any(feature = "alloc", feature = "kernel")))]
94 {
95 let mut messages_array: [Option<Message<'a>>; MAX_MESSAGES] =
96 [const { None }; MAX_MESSAGES];
97 for (i, message_opt) in messages.iter().take(count).enumerate() {
98 messages_array[i] = message_opt.clone();
99 }
100 Self {
101 messages: messages_array,
102 message_count: count,
103 }
104 }
105
106 #[cfg(any(feature = "alloc", feature = "kernel"))]
107 {
108 use crate::compat::vec_with_capacity;
109 use alloc::vec::Vec;
110 let mut messages_vec: Vec<Option<Message<'a>>> = vec_with_capacity(count);
111 for message_opt in messages.iter().take(count) {
112 messages_vec.push(message_opt.clone());
113 }
114 Self {
115 messages: messages_vec.into_boxed_slice(),
116 message_count: count,
117 }
118 }
119 }
120
121 #[inline]
137 #[must_use = "iterator is lazy and does nothing unless consumed"]
138 pub fn iter(&self) -> impl Iterator<Item = &Message<'a>> + '_ {
139 let messages_slice: &[Option<Message<'a>>] = &self.messages;
140 MessagesIter {
141 messages: messages_slice,
142 count: self.message_count,
143 pos: 0,
144 }
145 }
146
147 #[inline]
159 #[must_use]
160 pub fn len(&self) -> usize {
161 self.message_count
162 }
163
164 #[inline]
176 #[must_use]
177 pub fn is_empty(&self) -> bool {
178 self.len() == 0
179 }
180
181 #[inline]
195 #[must_use]
196 pub fn at(&self, index: usize) -> Option<&Message<'a>> {
197 if index >= self.message_count {
198 return None;
199 }
200 self.messages[index].as_ref()
201 }
202
203 #[must_use]
218 pub fn find(&self, name: &str) -> Option<&Message<'a>> {
219 self.iter().find(|m| m.name() == name)
220 }
221
222 pub(crate) const fn max_capacity() -> usize {
224 MAX_MESSAGES
225 }
226
227 #[cfg(not(any(feature = "alloc", feature = "kernel")))]
230 pub(crate) fn new_parse_buffer<'b>() -> [Option<Message<'b>>; MAX_MESSAGES] {
231 [const { None }; MAX_MESSAGES]
232 }
233
234 pub(crate) fn count_messages_and_signals<'b>(
237 parser: &mut crate::Parser<'b>,
238 ) -> crate::error::ParseResult<usize> {
239 use crate::{
240 BA_, BA_DEF_, BA_DEF_DEF_, BO_, BO_TX_BU_, BS_, BU_, CM_, EV_, NS_, SG_, SIG_GROUP_,
241 SIG_VALTYPE_, VAL_, VAL_TABLE_, VERSION,
242 };
243
244 let mut message_count = 0;
246
247 loop {
248 parser.skip_newlines_and_spaces();
249 if parser.starts_with(b"//") {
250 parser.skip_to_end_of_line();
251 continue;
252 }
253
254 let keyword_result = parser.find_next_keyword();
255 let keyword = match keyword_result {
256 Ok(kw) => kw,
257 Err(crate::error::ParseError::UnexpectedEof) => break,
258 Err(crate::error::ParseError::Expected(_)) => {
259 if parser.starts_with(b"//") {
260 parser.skip_to_end_of_line();
261 continue;
262 }
263 return Err(keyword_result.unwrap_err());
264 }
265 Err(e) => return Err(e),
266 };
267
268 match keyword {
269 NS_ => {
270 parser.skip_newlines_and_spaces();
271 let _ = parser.expect(b":").ok();
272 loop {
273 parser.skip_newlines_and_spaces();
274 if parser.is_empty() {
275 break;
276 }
277 if parser.starts_with(b" ") || parser.starts_with(b"\t") {
278 parser.skip_to_end_of_line();
279 continue;
280 }
281 if parser.starts_with(b"//") {
282 parser.skip_to_end_of_line();
283 continue;
284 }
285 if parser.starts_with(BS_.as_bytes())
286 || parser.starts_with(BU_.as_bytes())
287 || parser.starts_with(BO_.as_bytes())
288 || parser.starts_with(SG_.as_bytes())
289 || parser.starts_with(VERSION.as_bytes())
290 {
291 break;
292 }
293 parser.skip_to_end_of_line();
294 }
295 continue;
296 }
297 CM_ | BS_ | VAL_TABLE_ | BA_DEF_ | BA_DEF_DEF_ | BA_ | VAL_ | SIG_GROUP_
298 | SIG_VALTYPE_ | EV_ | BO_TX_BU_ => {
299 parser.skip_to_end_of_line();
300 continue;
301 }
302 VERSION | BU_ => {
303 parser.skip_to_end_of_line();
305 continue;
306 }
307 BO_ => {
308 if message_count >= MAX_MESSAGES {
310 return Err(crate::error::ParseError::Version(
311 crate::error::messages::NODES_TOO_MANY,
312 ));
313 }
314
315 parser.skip_newlines_and_spaces();
317 let _ = parser.parse_u32().ok();
318 parser.skip_newlines_and_spaces();
319 let _ = parser.parse_identifier().ok();
320 parser.skip_newlines_and_spaces();
321 let _ = parser.expect(b":").ok();
322 parser.skip_newlines_and_spaces();
323 let _ = parser.parse_u8().ok();
324 parser.skip_newlines_and_spaces();
325 let _ = parser.parse_identifier().ok();
326 parser.skip_to_end_of_line();
327
328 let mut signal_count = 0;
330 loop {
331 parser.skip_newlines_and_spaces();
332 if parser.starts_with(crate::SG_.as_bytes()) {
333 if let Some(next_byte) = parser.peek_byte_at(3) {
334 if matches!(next_byte, b' ' | b'\n' | b'\r' | b'\t') {
335 if signal_count >= crate::Signals::max_capacity() {
336 return Err(crate::error::ParseError::Version(
337 crate::error::messages::SIGNAL_RECEIVERS_TOO_MANY,
338 ));
339 }
340 signal_count += 1;
341 let _ = parser.find_next_keyword().ok();
342 parser.skip_to_end_of_line();
344 continue;
345 }
346 }
347 }
348 break;
349 }
350
351 message_count += 1;
352 continue;
353 }
354 SG_ => {
355 let _ = crate::Signal::parse(parser).ok();
357 continue;
358 }
359 _ => {
360 parser.skip_to_end_of_line();
361 continue;
362 }
363 }
364 }
365
366 Ok(message_count)
367 }
368}