dbc_rs/message/core.rs
1use super::{Message, Signals};
2use crate::{Signal, compat::String};
3
4impl Message {
5 #[cfg(feature = "std")]
6 pub(crate) fn new(
7 id: u32,
8 name: String<{ crate::MAX_NAME_SIZE }>,
9 dlc: u8,
10 sender: String<{ crate::MAX_NAME_SIZE }>,
11 signals: impl Into<Signals>,
12 ) -> Self {
13 // Validation should have been done prior (by builder or parse)
14 Self {
15 id,
16 name,
17 dlc,
18 sender,
19 signals: signals.into(),
20 }
21 }
22
23 pub(crate) fn new_from_signals(
24 id: u32,
25 name: &str,
26 dlc: u8,
27 sender: &str,
28 signals: &[Signal],
29 ) -> Self {
30 // Validation should have been done prior (by builder or parse)
31 let name_str: String<{ crate::MAX_NAME_SIZE }> = String::try_from(name)
32 .map_err(|_| crate::Error::Validation(crate::Error::MAX_NAME_SIZE_EXCEEDED))
33 .unwrap();
34 let sender_str: String<{ crate::MAX_NAME_SIZE }> = String::try_from(sender)
35 .map_err(|_| crate::Error::Validation(crate::Error::MAX_NAME_SIZE_EXCEEDED))
36 .unwrap();
37 Self {
38 id,
39 name: name_str,
40 dlc,
41 sender: sender_str,
42 signals: Signals::from_slice(signals),
43 }
44 }
45
46 /// Returns the CAN message ID.
47 ///
48 /// # Examples
49 ///
50 /// ```rust,no_run
51 /// use dbc_rs::Dbc;
52 ///
53 /// let dbc = Dbc::parse(r#"VERSION "1.0"\n\nBU_: ECM\n\nBO_ 256 EngineData : 8 ECM"#)?;
54 /// let message = dbc.messages().at(0).unwrap();
55 /// assert_eq!(message.id(), 256);
56 /// # Ok::<(), dbc_rs::Error>(())
57 /// ```
58 #[inline]
59 #[must_use]
60 pub fn id(&self) -> u32 {
61 self.id
62 }
63
64 /// Returns the message name.
65 ///
66 /// # Examples
67 ///
68 /// ```rust,no_run
69 /// use dbc_rs::Dbc;
70 ///
71 /// let dbc = Dbc::parse(r#"VERSION "1.0"\n\nBU_: ECM\n\nBO_ 256 EngineData : 8 ECM"#)?;
72 /// let message = dbc.messages().at(0).unwrap();
73 /// assert_eq!(message.name(), "EngineData");
74 /// # Ok::<(), dbc_rs::Error>(())
75 /// ```
76 #[inline]
77 #[must_use]
78 pub fn name(&self) -> &str {
79 self.name.as_str()
80 }
81
82 /// Returns the Data Length Code (DLC) in bytes.
83 ///
84 /// DLC specifies the size of the message payload. For classic CAN, this is 1-8 bytes.
85 /// For CAN FD, this can be up to 64 bytes.
86 ///
87 /// # Examples
88 ///
89 /// ```rust,no_run
90 /// use dbc_rs::Dbc;
91 ///
92 /// let dbc = Dbc::parse(r#"VERSION "1.0"\n\nBU_: ECM\n\nBO_ 256 EngineData : 8 ECM"#)?;
93 /// let message = dbc.messages().at(0).unwrap();
94 /// assert_eq!(message.dlc(), 8);
95 /// # Ok::<(), dbc_rs::Error>(())
96 /// ```
97 #[inline]
98 #[must_use]
99 pub fn dlc(&self) -> u8 {
100 self.dlc
101 }
102
103 #[inline]
104 #[must_use]
105 pub fn sender(&self) -> &str {
106 self.sender.as_str()
107 }
108
109 /// Get a reference to the signals collection
110 #[inline]
111 #[must_use]
112 pub fn signals(&self) -> &Signals {
113 &self.signals
114 }
115}
116
117#[cfg(test)]
118mod tests {
119 use super::*;
120 use crate::{Parser, Signal};
121
122 #[test]
123 fn test_message_getters_edge_cases() {
124 // Test with minimum values
125 let data = b"BO_ 0 A : 1 B";
126 let mut parser = Parser::new(data).unwrap();
127 let signals: &[Signal] = &[];
128 let message = Message::parse(&mut parser, signals).unwrap();
129
130 assert_eq!(message.id(), 0);
131 assert_eq!(message.name(), "A");
132 assert_eq!(message.dlc(), 1);
133 assert_eq!(message.sender(), "B");
134 }
135}