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