dbc_rs/dbc/message_list.rs
1use crate::{Error, MAX_MESSAGES, Message, Result, compat::Vec, error::lang};
2
3/// Encapsulates the messages array and count for a DBC
4///
5/// Uses `Vec<Message>` for dynamic sizing.
6#[derive(Debug, Clone, PartialEq, Eq, Hash)]
7pub struct MessageList {
8 messages: Vec<Message, { MAX_MESSAGES }>,
9}
10
11impl MessageList {
12 /// Create MessageList from a slice of messages by cloning them
13 pub(crate) fn new(messages: &[Message]) -> Result<Self> {
14 if let Some(err) = crate::check_max_limit(
15 messages.len(),
16 MAX_MESSAGES,
17 Error::Message(lang::NODES_TOO_MANY),
18 ) {
19 return Err(err);
20 }
21 let messages_vec: Vec<Message, { MAX_MESSAGES }> = messages.iter().cloned().collect();
22 Ok(Self {
23 messages: messages_vec,
24 })
25 }
26
27 /// Get an iterator over the messages
28 ///
29 /// # Examples
30 ///
31 /// ```rust,no_run
32 /// use dbc_rs::Dbc;
33 ///
34 /// let dbc = Dbc::parse("VERSION \"1.0\"\n\nBU_: ECM\n\nBO_ 256 Engine : 8 ECM")?;
35 /// let mut iter = dbc.messages().iter();
36 /// let message = iter.next().unwrap();
37 /// assert_eq!(message.name(), "Engine");
38 /// assert_eq!(message.id(), 256);
39 /// assert!(iter.next().is_none());
40 /// # Ok::<(), dbc_rs::Error>(())
41 /// ```
42 #[inline]
43 #[must_use = "iterator is lazy and does nothing unless consumed"]
44 pub fn iter(&self) -> impl Iterator<Item = &Message> + '_ {
45 self.messages.iter()
46 }
47
48 /// Get the number of messages
49 ///
50 /// # Examples
51 ///
52 /// ```rust,no_run
53 /// use dbc_rs::Dbc;
54 ///
55 /// let dbc = Dbc::parse("VERSION \"1.0\"\n\nBU_: ECM\n\nBO_ 256 Engine : 8 ECM")?;
56 /// assert_eq!(dbc.messages().len(), 1);
57 /// # Ok::<(), dbc_rs::Error>(())
58 /// ```
59 #[inline]
60 #[must_use]
61 pub fn len(&self) -> usize {
62 self.messages.len()
63 }
64
65 /// Returns `true` if there are no messages
66 ///
67 /// # Examples
68 ///
69 /// ```rust,no_run
70 /// use dbc_rs::Dbc;
71 ///
72 /// let dbc = Dbc::parse("VERSION \"1.0\"\n\nBU_: ECM")?;
73 /// assert!(dbc.messages().is_empty());
74 /// # Ok::<(), dbc_rs::Error>(())
75 /// ```
76 #[inline]
77 #[must_use]
78 pub fn is_empty(&self) -> bool {
79 self.len() == 0
80 }
81
82 /// Get a message by index, or None if index is out of bounds
83 ///
84 /// # Examples
85 ///
86 /// ```rust,no_run
87 /// use dbc_rs::Dbc;
88 ///
89 /// let dbc = Dbc::parse("VERSION \"1.0\"\n\nBU_: ECM\n\nBO_ 256 Engine : 8 ECM")?;
90 /// if let Some(message) = dbc.messages().at(0) {
91 /// assert_eq!(message.name(), "Engine");
92 /// }
93 /// # Ok::<(), dbc_rs::Error>(())
94 /// ```
95 #[inline]
96 #[must_use]
97 pub fn at(&self, index: usize) -> Option<&Message> {
98 self.messages.get(index)
99 }
100
101 /// Find a message by name, or None if not found
102 ///
103 /// # Examples
104 ///
105 /// ```rust,no_run
106 /// use dbc_rs::Dbc;
107 ///
108 /// let dbc = Dbc::parse("VERSION \"1.0\"\n\nBU_: ECM\n\nBO_ 256 Engine : 8 ECM")?;
109 /// if let Some(message) = dbc.messages().find("Engine") {
110 /// assert_eq!(message.name(), "Engine");
111 /// assert_eq!(message.id(), 256);
112 /// }
113 /// # Ok::<(), dbc_rs::Error>(())
114 /// ```
115 #[must_use]
116 pub fn find(&self, name: &str) -> Option<&Message> {
117 self.iter().find(|m| m.name() == name)
118 }
119
120 /// Find a message by CAN ID, or None if not found
121 ///
122 /// # Examples
123 ///
124 /// ```rust,no_run
125 /// use dbc_rs::Dbc;
126 ///
127 /// let dbc = Dbc::parse("VERSION \"1.0\"\n\nBU_: ECM\n\nBO_ 256 Engine : 8 ECM")?;
128 /// if let Some(message) = dbc.messages().find_by_id(256) {
129 /// assert_eq!(message.name(), "Engine");
130 /// assert_eq!(message.id(), 256);
131 /// }
132 /// # Ok::<(), dbc_rs::Error>(())
133 /// ```
134 #[must_use]
135 pub fn find_by_id(&self, id: u32) -> Option<&Message> {
136 self.iter().find(|m| m.id() == id)
137 }
138}