dbc_rs/signal/builder/
impls.rs1use super::SignalBuilder;
2use super::{ByteOrder, ReceiversBuilder};
3use crate::{builder_setter, builder_string_setter};
4
5impl SignalBuilder {
6 pub fn new() -> Self {
18 Self {
19 name: None,
20 start_bit: None,
21 length: None,
22 byte_order: None,
23 unsigned: None,
24 factor: None,
25 offset: None,
26 min: None,
27 max: None,
28 unit: None,
29 receivers: ReceiversBuilder::new(),
30 comment: None,
31 }
32 }
33
34 builder_string_setter!(name, "Sets the signal name.");
36 builder_string_setter!(
37 unit,
38 "Sets the unit of measurement for this signal (e.g., \"km/h\", \"rpm\", \"°C\")."
39 );
40 builder_string_setter!(
41 comment,
42 "Sets the comment text for this signal (from CM_ SG_ entry)."
43 );
44
45 builder_setter!(
47 start_bit,
48 u16,
49 "Sets the start bit position of the signal in the CAN message payload."
50 );
51 builder_setter!(length, u16, "Sets the length of the signal in bits.");
52 builder_setter!(
53 byte_order,
54 ByteOrder,
55 "Sets the byte order (endianness) of the signal."
56 );
57 builder_setter!(
58 unsigned,
59 bool,
60 "Sets whether the signal is unsigned (`true`) or signed (`false`)."
61 );
62 builder_setter!(
63 factor,
64 f64,
65 "Sets the scaling factor for converting raw values to physical values (physical = raw * factor + offset)."
66 );
67 builder_setter!(
68 offset,
69 f64,
70 "Sets the offset for converting raw values to physical values (physical = raw * factor + offset)."
71 );
72 builder_setter!(min, f64, "Sets the minimum physical value for this signal.");
73 builder_setter!(max, f64, "Sets the maximum physical value for this signal.");
74
75 #[must_use = "builder method returns modified builder"]
95 pub fn receivers(mut self, receivers: ReceiversBuilder) -> Self {
96 self.receivers = receivers;
97 self
98 }
99}
100
101impl Default for SignalBuilder {
102 fn default() -> Self {
103 Self::new()
104 }
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110
111 fn minimal_signal() -> SignalBuilder {
112 SignalBuilder::new()
113 .name("TestSignal")
114 .start_bit(0)
115 .length(8)
116 .byte_order(ByteOrder::LittleEndian)
117 .unsigned(true)
118 .factor(1.0)
119 .offset(0.0)
120 .min(0.0)
121 .max(255.0)
122 .receivers(ReceiversBuilder::new().none())
123 }
124
125 #[test]
126 fn test_signal_builder_minimal() {
127 let signal = minimal_signal().build().unwrap();
128
129 assert_eq!(signal.name(), "TestSignal");
130 assert_eq!(signal.start_bit(), 0);
131 assert_eq!(signal.length(), 8);
132 assert_eq!(signal.byte_order(), ByteOrder::LittleEndian);
133 assert!(signal.is_unsigned());
134 assert_eq!(signal.factor(), 1.0);
135 assert_eq!(signal.offset(), 0.0);
136 assert_eq!(signal.min(), 0.0);
137 assert_eq!(signal.max(), 255.0);
138 assert!(signal.unit().is_none());
139 }
140
141 #[test]
142 fn test_signal_builder_with_unit() {
143 let signal = minimal_signal().unit("rpm").build().unwrap();
144 assert_eq!(signal.unit(), Some("rpm"));
145 }
146
147 #[test]
148 fn test_signal_builder_signed() {
149 let signal = minimal_signal().unsigned(false).build().unwrap();
150 assert!(!signal.is_unsigned());
151 }
152
153 #[test]
154 fn test_signal_builder_big_endian() {
155 let signal = minimal_signal().byte_order(ByteOrder::BigEndian).build().unwrap();
156 assert_eq!(signal.byte_order(), ByteOrder::BigEndian);
157 }
158
159 #[test]
160 fn test_signal_builder_with_receivers() {
161 let signal = minimal_signal()
162 .receivers(ReceiversBuilder::new().add_node("ECM").add_node("TCM"))
163 .build()
164 .unwrap();
165
166 assert_eq!(signal.receivers().len(), 2);
167 }
168
169 #[test]
170 fn test_signal_builder_with_comment() {
171 let signal = minimal_signal()
172 .comment("Engine speed calculated over 720 degrees")
173 .build()
174 .unwrap();
175
176 assert_eq!(
177 signal.comment(),
178 Some("Engine speed calculated over 720 degrees")
179 );
180 }
181
182 #[test]
183 fn test_signal_builder_without_comment() {
184 let signal = minimal_signal().build().unwrap();
185 assert_eq!(signal.comment(), None);
186 }
187}