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}