dbc_rs/message/builder/
impls.rs

1use super::MessageBuilder;
2use crate::{SignalBuilder, builder_setter, builder_string_setter};
3use std::vec::Vec;
4
5impl MessageBuilder {
6    /// Creates a new `MessageBuilder` with no fields set.
7    ///
8    /// # Examples
9    ///
10    /// ```rust,no_run
11    /// use dbc_rs::MessageBuilder;
12    ///
13    /// let builder = MessageBuilder::new();
14    /// // Must set id, name, dlc, and sender before building
15    /// # Ok::<(), dbc_rs::Error>(())
16    /// ```
17    pub fn new() -> Self {
18        Self {
19            id: None,
20            name: None,
21            dlc: None,
22            sender: None,
23            signals: Vec::new(),
24            comment: None,
25        }
26    }
27
28    // Scalar field setters generated by macros
29    builder_setter!(
30        id,
31        u32,
32        "Sets the CAN message ID (11-bit or 29-bit identifier)."
33    );
34    builder_setter!(
35        dlc,
36        u8,
37        "Sets the Data Length Code (DLC) - the number of data bytes in the message (0-8 for standard CAN, 0-64 for CAN FD)."
38    );
39
40    // String field setters generated by macros
41    builder_string_setter!(name, "Sets the message name.");
42    builder_string_setter!(
43        sender,
44        "Sets the sender (transmitter) ECU node name for this message."
45    );
46    builder_string_setter!(
47        comment,
48        "Sets the comment text for this message (from CM_ BO_ entry)."
49    );
50
51    /// Adds a signal to the message.
52    ///
53    /// # Arguments
54    ///
55    /// * `signal` - A `SignalBuilder` to add to this message
56    ///
57    /// # Examples
58    ///
59    /// ```rust,no_run
60    /// use dbc_rs::{MessageBuilder, SignalBuilder, ByteOrder};
61    ///
62    /// let signal = SignalBuilder::new()
63    ///     .name("EngineSpeed")
64    ///     .start_bit(0)
65    ///     .length(16)
66    ///     .byte_order(ByteOrder::LittleEndian);
67    ///
68    /// let builder = MessageBuilder::new()
69    ///     .add_signal(signal);
70    /// # Ok::<(), dbc_rs::Error>(())
71    /// ```
72    #[must_use = "builder method returns modified builder"]
73    pub fn add_signal(mut self, signal: SignalBuilder) -> Self {
74        self.signals.push(signal);
75        self
76    }
77
78    /// Adds multiple signals to the message.
79    ///
80    /// # Arguments
81    ///
82    /// * `signals` - An iterator of `SignalBuilder` items to add
83    ///
84    /// # Examples
85    ///
86    /// ```rust,no_run
87    /// use dbc_rs::{MessageBuilder, SignalBuilder, ByteOrder};
88    ///
89    /// let signals = vec![
90    ///     SignalBuilder::new().name("Signal1").start_bit(0).length(8).byte_order(ByteOrder::LittleEndian),
91    ///     SignalBuilder::new().name("Signal2").start_bit(8).length(8).byte_order(ByteOrder::LittleEndian),
92    /// ];
93    ///
94    /// let builder = MessageBuilder::new()
95    ///     .add_signals(signals);
96    /// # Ok::<(), dbc_rs::Error>(())
97    /// ```
98    #[must_use = "builder method returns modified builder"]
99    pub fn add_signals(mut self, signals: impl IntoIterator<Item = SignalBuilder>) -> Self {
100        self.signals.extend(signals);
101        self
102    }
103
104    /// Replaces all signals in the message with the provided signals.
105    ///
106    /// Clears any existing signals and adds the new ones.
107    ///
108    /// # Arguments
109    ///
110    /// * `signals` - A vector of `SignalBuilder` items to set
111    ///
112    /// # Examples
113    ///
114    /// ```rust,no_run
115    /// use dbc_rs::{MessageBuilder, SignalBuilder, ByteOrder};
116    ///
117    /// let new_signals = vec![
118    ///     SignalBuilder::new().name("NewSignal").start_bit(0).length(8).byte_order(ByteOrder::LittleEndian),
119    /// ];
120    ///
121    /// let builder = MessageBuilder::new()
122    ///     .signals(new_signals);
123    /// # Ok::<(), dbc_rs::Error>(())
124    /// ```
125    #[must_use = "builder method returns modified builder"]
126    pub fn signals(mut self, signals: Vec<SignalBuilder>) -> Self {
127        self.signals = signals;
128        self
129    }
130
131    /// Removes all signals from the message.
132    ///
133    /// # Examples
134    ///
135    /// ```rust,no_run
136    /// use dbc_rs::MessageBuilder;
137    ///
138    /// let builder = MessageBuilder::new()
139    ///     .clear_signals();
140    /// # Ok::<(), dbc_rs::Error>(())
141    /// ```
142    #[must_use = "builder method returns modified builder"]
143    pub fn clear_signals(mut self) -> Self {
144        self.signals.clear();
145        self
146    }
147}
148
149impl Default for MessageBuilder {
150    fn default() -> Self {
151        Self::new()
152    }
153}
154
155#[cfg(test)]
156mod tests {
157    use super::*;
158    use crate::{ByteOrder, ReceiversBuilder};
159
160    fn minimal_signal() -> SignalBuilder {
161        SignalBuilder::new()
162            .name("TestSignal")
163            .start_bit(0)
164            .length(8)
165            .byte_order(ByteOrder::LittleEndian)
166            .unsigned(true)
167            .factor(1.0)
168            .offset(0.0)
169            .min(0.0)
170            .max(255.0)
171            .receivers(ReceiversBuilder::new().none())
172    }
173
174    fn minimal_message() -> MessageBuilder {
175        MessageBuilder::new().id(256).name("TestMessage").dlc(8).sender("ECM")
176    }
177
178    #[test]
179    fn test_message_builder_with_signal() {
180        let message = minimal_message().add_signal(minimal_signal()).build().unwrap();
181
182        assert_eq!(message.signals().len(), 1);
183        assert_eq!(message.signals().at(0).unwrap().name(), "TestSignal");
184    }
185
186    #[test]
187    fn test_message_builder_add_signals() {
188        let sig1 = minimal_signal().name("Signal1");
189        let sig2 = minimal_signal().name("Signal2").start_bit(8);
190
191        let message = minimal_message().add_signals(vec![sig1, sig2]).build().unwrap();
192
193        assert_eq!(message.signals().len(), 2);
194    }
195
196    #[test]
197    fn test_message_builder_signals() {
198        let sig1 = minimal_signal().name("Signal1");
199        let sig2 = minimal_signal().name("Signal2").start_bit(8);
200
201        let message = minimal_message().signals(vec![sig1, sig2]).build().unwrap();
202
203        assert_eq!(message.signals().len(), 2);
204    }
205
206    #[test]
207    fn test_message_builder_clear_signals() {
208        let message =
209            minimal_message().add_signal(minimal_signal()).clear_signals().build().unwrap();
210
211        assert_eq!(message.signals().len(), 0);
212    }
213}