dbc_rs/message/builder/
mod.rs

1use crate::{Error, Message, Result, Signal, SignalBuilder};
2use std::string::String;
3
4#[derive(Debug)]
5pub struct MessageBuilder {
6    id: Option<u32>,
7    name: Option<String>,
8    dlc: Option<u8>,
9    sender: Option<String>,
10    signals: Vec<SignalBuilder>,
11}
12
13impl MessageBuilder {
14    pub fn new() -> Self {
15        Self {
16            id: None,
17            name: None,
18            dlc: None,
19            sender: None,
20            signals: Vec::new(),
21        }
22    }
23
24    #[must_use = "builder method returns modified builder"]
25    pub fn id(mut self, id: u32) -> Self {
26        self.id = Some(id);
27        self
28    }
29
30    #[must_use = "builder method returns modified builder"]
31    pub fn name(mut self, name: impl AsRef<str>) -> Self {
32        self.name = Some(name.as_ref().to_string());
33        self
34    }
35
36    #[must_use = "builder method returns modified builder"]
37    pub fn dlc(mut self, dlc: u8) -> Self {
38        self.dlc = Some(dlc);
39        self
40    }
41
42    #[must_use = "builder method returns modified builder"]
43    pub fn sender(mut self, sender: impl AsRef<str>) -> Self {
44        self.sender = Some(sender.as_ref().to_string());
45        self
46    }
47
48    #[must_use = "builder method returns modified builder"]
49    pub fn add_signal(mut self, signal: SignalBuilder) -> Self {
50        self.signals.push(signal);
51        self
52    }
53
54    #[must_use = "builder method returns modified builder"]
55    pub fn add_signals(mut self, signals: impl IntoIterator<Item = SignalBuilder>) -> Self {
56        self.signals.extend(signals);
57        self
58    }
59
60    #[must_use = "builder method returns modified builder"]
61    pub fn signals(mut self, signals: Vec<SignalBuilder>) -> Self {
62        self.signals = signals;
63        self
64    }
65
66    #[must_use = "builder method returns modified builder"]
67    pub fn clear_signals(mut self) -> Self {
68        self.signals.clear();
69        self
70    }
71
72    fn extract_fields(self) -> Result<(u32, String, u8, String, Vec<SignalBuilder>)> {
73        let id = self.id.ok_or(Error::Message(Error::MESSAGE_ID_REQUIRED))?;
74        let name = self.name.ok_or(Error::Message(Error::MESSAGE_NAME_EMPTY))?;
75        let dlc = self.dlc.ok_or(Error::Message(Error::MESSAGE_DLC_REQUIRED))?;
76        let sender = self.sender.ok_or(Error::Message(Error::MESSAGE_SENDER_EMPTY))?;
77        Ok((id, name, dlc, sender, self.signals))
78    }
79
80    #[must_use = "validation result should be checked"]
81    pub fn validate(mut self) -> Result<Self> {
82        // Extract fields (this consumes signals, but we'll reconstruct)
83        let signals_clone = self.signals.clone();
84        let id = self.id.ok_or(Error::Message(Error::MESSAGE_ID_REQUIRED))?;
85        let name = self.name.ok_or(Error::Message(Error::MESSAGE_NAME_EMPTY))?;
86        let dlc = self.dlc.ok_or(Error::Message(Error::MESSAGE_DLC_REQUIRED))?;
87        let sender = self.sender.ok_or(Error::Message(Error::MESSAGE_SENDER_EMPTY))?;
88        // Build signals for validation using cloned signals
89        let built_signals: Vec<Signal> = signals_clone
90            .into_iter()
91            .map(|sig_builder| sig_builder.build())
92            .collect::<Result<Vec<_>>>()?;
93        // Validate signals directly
94        Message::validate_internal(id, &name, dlc, &sender, &built_signals)?;
95        // Reconstruct from original data (signals were cloned before, so use original)
96        self.id = Some(id);
97        self.name = Some(name);
98        self.dlc = Some(dlc);
99        self.sender = Some(sender);
100        // signals are already set (we cloned before, so self.signals is still there)
101        Ok(self)
102    }
103}
104
105impl Default for MessageBuilder {
106    fn default() -> Self {
107        Self::new()
108    }
109}
110
111impl MessageBuilder {
112    pub fn build(self) -> Result<Message> {
113        let (id, name, dlc, sender, signals) = self.extract_fields()?;
114        // Build all signals first
115        let built_signals: Vec<Signal> = signals
116            .into_iter()
117            .map(|sig_builder| sig_builder.build())
118            .collect::<Result<Vec<_>>>()?;
119        // Validate before construction
120        Message::validate_internal(id, &name, dlc, &sender, &built_signals)?;
121        // Convert name and sender to String<{ MAX_NAME_SIZE }>
122
123        Ok(Message::new(
124            id,
125            name.into(),
126            dlc,
127            sender.into(),
128            built_signals,
129        ))
130    }
131}