openigtlink_rust/protocol/
factory.rs1use crate::error::{IgtlError, Result};
7use crate::protocol::any_message::AnyMessage;
8use crate::protocol::header::Header;
9use crate::protocol::message::IgtlMessage;
10use crate::protocol::types::*;
11
12pub struct MessageFactory;
30
31impl MessageFactory {
32 pub fn new() -> Self {
34 MessageFactory
35 }
36
37 pub fn decode_any(&self, header: &Header, body: &[u8], verify_crc: bool) -> Result<AnyMessage> {
72 use crate::protocol::crc::calculate_crc;
73
74 if verify_crc {
76 let calculated_crc = calculate_crc(body);
77 if calculated_crc != header.crc {
78 return Err(IgtlError::CrcMismatch {
79 expected: header.crc,
80 actual: calculated_crc,
81 });
82 }
83 }
84
85 let mut full_msg = header.encode().to_vec();
87 full_msg.extend_from_slice(body);
88
89 let type_name = header.type_name.as_str()?;
91
92 match type_name {
94 "TRANSFORM" => Ok(AnyMessage::Transform(
95 IgtlMessage::<TransformMessage>::decode_with_options(&full_msg, false)?,
96 )),
97 "STATUS" => Ok(AnyMessage::Status(
98 IgtlMessage::<StatusMessage>::decode_with_options(&full_msg, false)?,
99 )),
100 "CAPABILITY" => Ok(AnyMessage::Capability(
101 IgtlMessage::<CapabilityMessage>::decode_with_options(&full_msg, false)?,
102 )),
103 "IMAGE" => Ok(AnyMessage::Image(
104 IgtlMessage::<ImageMessage>::decode_with_options(&full_msg, false)?,
105 )),
106 "POSITION" => Ok(AnyMessage::Position(
107 IgtlMessage::<PositionMessage>::decode_with_options(&full_msg, false)?,
108 )),
109 "STRING" => Ok(AnyMessage::String(
110 IgtlMessage::<StringMessage>::decode_with_options(&full_msg, false)?,
111 )),
112 "QTDATA" => Ok(AnyMessage::QtData(
113 IgtlMessage::<QtDataMessage>::decode_with_options(&full_msg, false)?,
114 )),
115 "TDATA" => Ok(AnyMessage::TData(
116 IgtlMessage::<TDataMessage>::decode_with_options(&full_msg, false)?,
117 )),
118 "SENSOR" => Ok(AnyMessage::Sensor(
119 IgtlMessage::<SensorMessage>::decode_with_options(&full_msg, false)?,
120 )),
121 "POINT" => Ok(AnyMessage::Point(
122 IgtlMessage::<PointMessage>::decode_with_options(&full_msg, false)?,
123 )),
124 "TRAJECTORY" => Ok(AnyMessage::Trajectory(
125 IgtlMessage::<TrajectoryMessage>::decode_with_options(&full_msg, false)?,
126 )),
127 "NDARRAY" => Ok(AnyMessage::NdArray(
128 IgtlMessage::<NdArrayMessage>::decode_with_options(&full_msg, false)?,
129 )),
130 "BIND" => Ok(AnyMessage::Bind(
131 IgtlMessage::<BindMessage>::decode_with_options(&full_msg, false)?,
132 )),
133 "COLORTABLE" => Ok(AnyMessage::ColorTable(
134 IgtlMessage::<ColorTableMessage>::decode_with_options(&full_msg, false)?,
135 )),
136 "IMGMETA" => Ok(AnyMessage::ImgMeta(
137 IgtlMessage::<ImgMetaMessage>::decode_with_options(&full_msg, false)?,
138 )),
139 "LBMETA" => Ok(AnyMessage::LbMeta(
140 IgtlMessage::<LbMetaMessage>::decode_with_options(&full_msg, false)?,
141 )),
142 "POLYDATA" => Ok(AnyMessage::PolyData(
143 IgtlMessage::<PolyDataMessage>::decode_with_options(&full_msg, false)?,
144 )),
145 "VIDEO" => Ok(AnyMessage::Video(
146 IgtlMessage::<VideoMessage>::decode_with_options(&full_msg, false)?,
147 )),
148 "VIDEOMETA" => Ok(AnyMessage::VideoMeta(
149 IgtlMessage::<VideoMetaMessage>::decode_with_options(&full_msg, false)?,
150 )),
151 "COMMAND" => Ok(AnyMessage::Command(
152 IgtlMessage::<CommandMessage>::decode_with_options(&full_msg, false)?,
153 )),
154
155 "GET_TRANS" => Ok(AnyMessage::GetTransform(
157 IgtlMessage::<GetTransformMessage>::decode_with_options(&full_msg, false)?,
158 )),
159 "GET_STATUS" => Ok(AnyMessage::GetStatus(
160 IgtlMessage::<GetStatusMessage>::decode_with_options(&full_msg, false)?,
161 )),
162 "GET_CAPABIL" => Ok(AnyMessage::GetCapability(IgtlMessage::<
163 GetCapabilityMessage,
164 >::decode_with_options(
165 &full_msg, false
166 )?)),
167 "GET_IMAGE" => Ok(AnyMessage::GetImage(
168 IgtlMessage::<GetImageMessage>::decode_with_options(&full_msg, false)?,
169 )),
170 "GET_IMGMETA" => Ok(AnyMessage::GetImgMeta(
171 IgtlMessage::<GetImgMetaMessage>::decode_with_options(&full_msg, false)?,
172 )),
173 "GET_LBMETA" => Ok(AnyMessage::GetLbMeta(
174 IgtlMessage::<GetLbMetaMessage>::decode_with_options(&full_msg, false)?,
175 )),
176 "GET_POINT" => Ok(AnyMessage::GetPoint(
177 IgtlMessage::<GetPointMessage>::decode_with_options(&full_msg, false)?,
178 )),
179 "GET_TDATA" => Ok(AnyMessage::GetTData(
180 IgtlMessage::<GetTDataMessage>::decode_with_options(&full_msg, false)?,
181 )),
182
183 "RTS_TRANS" => Ok(AnyMessage::RtsTransform(
185 IgtlMessage::<RtsTransformMessage>::decode_with_options(&full_msg, false)?,
186 )),
187 "RTS_STATUS" => Ok(AnyMessage::RtsStatus(
188 IgtlMessage::<RtsStatusMessage>::decode_with_options(&full_msg, false)?,
189 )),
190 "RTS_CAPABIL" => Ok(AnyMessage::RtsCapability(IgtlMessage::<
191 RtsCapabilityMessage,
192 >::decode_with_options(
193 &full_msg, false
194 )?)),
195 "RTS_IMAGE" => Ok(AnyMessage::RtsImage(
196 IgtlMessage::<RtsImageMessage>::decode_with_options(&full_msg, false)?,
197 )),
198 "RTS_TDATA" => Ok(AnyMessage::RtsTData(
199 IgtlMessage::<RtsTDataMessage>::decode_with_options(&full_msg, false)?,
200 )),
201
202 "STT_TDATA" => Ok(AnyMessage::StartTData(
204 IgtlMessage::<StartTDataMessage>::decode_with_options(&full_msg, false)?,
205 )),
206 "STP_TRANS" => Ok(AnyMessage::StopTransform(IgtlMessage::<
207 StopTransformMessage,
208 >::decode_with_options(
209 &full_msg, false
210 )?)),
211 "STP_POSITION" => Ok(AnyMessage::StopPosition(
212 IgtlMessage::<StopPositionMessage>::decode_with_options(&full_msg, false)?,
213 )),
214 "STP_QTDATA" => Ok(AnyMessage::StopQtData(
215 IgtlMessage::<StopQtDataMessage>::decode_with_options(&full_msg, false)?,
216 )),
217 "STP_TDATA" => Ok(AnyMessage::StopTData(
218 IgtlMessage::<StopTDataMessage>::decode_with_options(&full_msg, false)?,
219 )),
220 "STP_IMAGE" => Ok(AnyMessage::StopImage(
221 IgtlMessage::<StopImageMessage>::decode_with_options(&full_msg, false)?,
222 )),
223 "STP_NDARRAY" => Ok(AnyMessage::StopNdArray(
224 IgtlMessage::<StopNdArrayMessage>::decode_with_options(&full_msg, false)?,
225 )),
226
227 _ => Ok(AnyMessage::Unknown {
229 header: header.clone(),
230 body: body.to_vec(),
231 }),
232 }
233 }
234}
235
236impl Default for MessageFactory {
237 fn default() -> Self {
238 Self::new()
239 }
240}
241
242#[cfg(test)]
243mod tests {
244 use super::*;
245 use crate::protocol::types::TransformMessage;
246
247 #[test]
248 fn test_factory_decode_transform() {
249 let transform = TransformMessage::identity();
250 let msg = IgtlMessage::new(transform, "TestDevice").unwrap();
251 let encoded = msg.encode().unwrap();
252
253 let header = Header::decode(&encoded[..Header::SIZE]).unwrap();
255 let body = &encoded[Header::SIZE..];
256
257 let factory = MessageFactory::new();
259 let any_msg = factory.decode_any(&header, body, true).unwrap();
260
261 assert_eq!(any_msg.message_type(), "TRANSFORM");
262 assert!(any_msg.as_transform().is_some());
263 assert_eq!(any_msg.device_name().unwrap(), "TestDevice");
264 }
265
266 #[test]
267 fn test_factory_decode_status() {
268 let status = StatusMessage::ok("Test message");
269 let msg = IgtlMessage::new(status, "StatusDevice").unwrap();
270 let encoded = msg.encode().unwrap();
271
272 let header = Header::decode(&encoded[..Header::SIZE]).unwrap();
273 let body = &encoded[Header::SIZE..];
274
275 let factory = MessageFactory::new();
276 let any_msg = factory.decode_any(&header, body, true).unwrap();
277
278 assert_eq!(any_msg.message_type(), "STATUS");
279 assert!(any_msg.as_status().is_some());
280 }
281
282 #[test]
283 fn test_factory_unknown_type() {
284 use crate::protocol::header::{DeviceName, Timestamp, TypeName};
286
287 let header = Header {
288 version: 2,
289 type_name: TypeName::new("CUSTOM").unwrap(),
290 device_name: DeviceName::new("Device").unwrap(),
291 timestamp: Timestamp::now(),
292 body_size: 4,
293 crc: 0,
294 };
295
296 let body = vec![1, 2, 3, 4];
297
298 let factory = MessageFactory::new();
299 let any_msg = factory.decode_any(&header, &body, false).unwrap();
300
301 assert!(any_msg.is_unknown());
302 assert_eq!(any_msg.message_type(), "CUSTOM");
303 }
304
305 #[test]
306 fn test_factory_crc_verification() {
307 let transform = TransformMessage::identity();
308 let msg = IgtlMessage::new(transform, "TestDevice").unwrap();
309 let mut encoded = msg.encode().unwrap();
310
311 let header = Header::decode(&encoded[..Header::SIZE]).unwrap();
312
313 encoded[Header::SIZE] ^= 0xFF;
315 let body = &encoded[Header::SIZE..];
316
317 let factory = MessageFactory::new();
318
319 let result = factory.decode_any(&header, body, true);
321 assert!(result.is_err());
322
323 let result = factory.decode_any(&header, body, false);
325 assert!(result.is_ok());
326 }
327}