milstd1553b_parser/
parser.rs1use crate::core::{Bus, Word, WordType};
4use crate::encoding::{ManchesterDecoder, ManchesterEncoder};
5use crate::error::Result;
6use crate::message::{Command, Message, StatusWord};
7
8#[derive(Debug, Clone)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub struct Transaction {
12 pub bus: Bus,
14 pub message: Message,
16 pub timestamp_us: Option<u64>,
18}
19
20pub struct Parser {
22 pub bus: Bus,
24}
25
26impl Parser {
27 pub fn new(bus: Bus) -> Self {
29 Parser { bus }
30 }
31
32 pub fn parse_word(&self, data: &[u8]) -> Result<Word> {
36 let word_value = ManchesterDecoder::decode_word(data)?;
37 self.identify_word_type_and_create(word_value)
39 }
40
41 pub fn parse_words(&self, data: &[u8]) -> Result<Vec<Word>> {
43 let mut words = Vec::new();
44 let mut offset = 0;
45
46 while offset + 5 <= data.len() {
47 let word = self.parse_word(&data[offset..offset + 5])?;
48 words.push(word);
49 offset += 5;
50 }
51
52 Ok(words)
53 }
54
55 pub fn parse_transaction(&self, data: &[u8]) -> Result<Transaction> {
63 let words = self.parse_words(data)?;
64
65 if words.is_empty() {
66 return Err(crate::error::ParseError::insufficient_data(
67 "No words to parse".to_string(),
68 ));
69 }
70
71 let message = self.parse_message(&words)?;
73
74 Ok(Transaction {
75 bus: self.bus,
76 message,
77 timestamp_us: None,
78 })
79 }
80
81 fn parse_message(&self, words: &[Word]) -> Result<Message> {
83 if words.is_empty() {
84 return Err(crate::error::ParseError::insufficient_data(
85 "Empty word sequence".to_string(),
86 ));
87 }
88
89 let first_word = words[0];
90
91 match first_word.word_type() {
92 WordType::Command => {
93 let command = Command::from_word(&first_word)?;
94
95 if words.len() > 1 {
97 let mut data_words = Vec::new();
98 for word in &words[1..] {
99 if word.word_type() == WordType::Data {
100 data_words.push(*word);
101 } else {
102 break; }
104 }
105
106 if !data_words.is_empty() {
107 Ok(Message::CommandData {
108 command,
109 data_words,
110 })
111 } else {
112 Ok(Message::CommandOnly(command))
113 }
114 } else {
115 Ok(Message::CommandOnly(command))
116 }
117 }
118 WordType::Status => {
119 let status = StatusWord::from_word(&first_word)?;
120 Ok(Message::Status(status))
121 }
122 _ => Err(crate::error::ParseError::invalid_message_type(
123 "Message must start with command or status word".to_string(),
124 )),
125 }
126 }
127
128 fn identify_word_type_and_create(&self, word_value: u32) -> Result<Word> {
130 Word::new(word_value, WordType::Data)
136 }
137
138 pub fn encode_command(&self, command: &Command) -> Result<Vec<u8>> {
140 let word = command.to_word()?;
141 let encoded = ManchesterEncoder::encode_word(word.data());
142 Ok(encoded)
143 }
144
145 pub fn encode_status(&self, status: &StatusWord) -> Result<Vec<u8>> {
147 let word = status.to_word()?;
148 let encoded = ManchesterEncoder::encode_word(word.data());
149 Ok(encoded)
150 }
151
152 pub fn encode_data_words(&self, data: &[u16]) -> Result<Vec<u8>> {
154 let mut encoded = Vec::new();
155
156 for &value in data {
157 let parity = Word::calculate_parity(value) as u32;
158 let word_value = (parity << 17) | ((value as u32) << 1);
159 let word = Word::new(word_value, WordType::Data)?;
160
161 let word_encoded = ManchesterEncoder::encode_word(word.data());
162 encoded.extend(word_encoded);
163 }
164
165 Ok(encoded)
166 }
167}
168
169pub struct ParserBuilder {
171 bus: Bus,
172}
173
174impl ParserBuilder {
175 pub fn new() -> Self {
177 ParserBuilder { bus: Bus::BusA }
178 }
179
180 pub fn with_bus(mut self, bus: Bus) -> Self {
182 self.bus = bus;
183 self
184 }
185
186 pub fn build(self) -> Parser {
188 Parser::new(self.bus)
189 }
190}
191
192impl Default for ParserBuilder {
193 fn default() -> Self {
194 Self::new()
195 }
196}
197
198#[cfg(test)]
199mod tests {
200 use super::*;
201 use crate::core::Address;
202 use crate::message::{CommandType, SubAddress};
203
204 #[test]
205 fn test_parser_creation() {
206 let parser = Parser::new(Bus::BusA);
207 assert_eq!(parser.bus, Bus::BusA);
208 }
209
210 #[test]
211 fn test_parser_builder() {
212 let parser = ParserBuilder::new().with_bus(Bus::BusB).build();
213 assert_eq!(parser.bus, Bus::BusB);
214 }
215
216 #[test]
217 fn test_encode_command() -> Result<()> {
218 let parser = Parser::new(Bus::BusA);
219 let cmd = Command::new(
220 Address::new(5)?,
221 CommandType::Transmit,
222 SubAddress::new(10)?,
223 16,
224 )?;
225
226 let encoded = parser.encode_command(&cmd)?;
227 assert!(!encoded.is_empty());
228 Ok(())
229 }
230
231 #[test]
232 fn test_parse_word_roundtrip() -> Result<()> {
233 let parser = Parser::new(Bus::BusA);
234
235 let original_data = 0x12345u32;
237 let parity = Word::calculate_parity(original_data as u16) as u32;
238 let word_value = (parity << 17) | (original_data << 1);
239 let original_word = Word::new(word_value, WordType::Data)?;
240
241 let encoded = ManchesterEncoder::encode_word(original_word.data());
243
244 let decoded_word = parser.parse_word(&encoded)?;
246
247 assert_eq!(decoded_word.data(), original_word.data());
249 Ok(())
250 }
251}