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}