1use crate::{
10 common::{
11 GenericHeader, Pdu, PduHeader, SerializedLength,
12 data_types::{
13 ClockTime, EntityCoordinateVector, EntityId, EntityType, EulerAngles, WorldCoordinate,
14 minefield_identifier::MinefieldIdentifier, point::Point,
15 },
16 enums::{
17 ForceId, MinefieldSensorTypes, MinefieldStateProtocolMode, PduType, ProtocolFamily,
18 },
19 },
20 define_pdu,
21};
22
23define_pdu! {
24 #[derive(Debug)]
25 pub struct MinefieldStatePdu {
27 header: PduHeader,
28 pdu_type: PduType::MinefieldState,
29 protocol_family: ProtocolFamily::Minefield,
30 fields: {
31 pub minefield_id: MinefieldIdentifier,
32 pub minefield_sequence: u16,
33 pub force_id: ForceId,
34 pub number_of_perimeter_points: u8,
35 pub minefield_type: EntityType,
36 pub number_of_mine_types: u16,
37 pub minefield_location: WorldCoordinate,
38 pub minefield_orientation: EulerAngles,
39 pub appearance: u16,
40 pub protocol_mode: MinefieldStateProtocolMode,
41 pub perimeter_points: Vec<Point>,
42 pub mine_type: Vec<EntityType>,
43 }
44 }
45}
46
47define_pdu! {
48 #[derive(Debug)]
49 pub struct MinefieldQueryPdu {
51 header: PduHeader,
52 pdu_type: PduType::MinefieldQuery,
53 protocol_family: ProtocolFamily::Minefield,
54 fields: {
55 pub minefield_id: MinefieldIdentifier,
56 pub requesting_entity_id: EntityId,
57 pub request_id: u8,
58 pub number_of_perimeter_points: u8,
59 padding: u8,
60 pub number_of_sensor_types: u8,
61 pub data_filter: u32,
62 pub requested_mine_type: EntityType,
63 pub requested_perimeter_points: Vec<Point>,
64 pub sensor_types: Vec<MinefieldSensorTypes>,
65 }
66 }
67}
68
69define_pdu! {
70 #[derive(Debug)]
71 pub struct MinefieldDataPdu {
73 header: PduHeader,
74 pdu_type: PduType::MinefieldData,
75 protocol_family: ProtocolFamily::Minefield,
76 fields: {
77 pub minefield_id: MinefieldIdentifier,
78 pub requesting_entity_id: EntityId,
79 pub minefield_sequence_number: u16,
80 pub request_id: u8,
81 pub pdu_sequence_number: u8,
82 pub number_of_pdus: u8,
83 pub number_of_mines_in_this_pdu: u8,
84 pub number_of_sensor_types: u8,
85 padding: u8,
86 pub data_filter: u32,
87 pub mine_type: EntityType,
88 pub sensor_types: Vec<MinefieldSensorTypes>,
89 pub mine_location: Vec<EntityCoordinateVector>,
90 pub ground_burial_depth_offset: Vec<Option<f32>>,
91 pub water_burial_depth_offset: Vec<Option<f32>>,
92 pub snow_burial_depth_offset: Vec<Option<f32>>,
93 pub mine_orientation: Vec<Option<EulerAngles>>,
94 pub thermal_contrast: Vec<Option<f32>>,
95 pub reflectance: Vec<Option<f32>>,
96 pub mine_emplacement_time: Vec<Option<ClockTime>>,
97 pub mine_entity_id: Vec<Option<u16>>,
98 pub fusing: Vec<Option<u16>>,
99 pub scalar_detection_coefficient: Vec<Option<u8>>,
100 pub paint_scheme: Vec<Option<u8>>,
101 pub number_of_trip_wires: Vec<Option<u8>>,
102 pub number_of_vertices: Vec<Option<u8>>,
103 pub vertices: Vec<Option<Vec<EntityCoordinateVector>>>,
104 }
105 }
106}
107
108define_pdu! {
109 #[derive(Debug)]
110 pub struct MinefieldResponseNackPdu {
112 header: PduHeader,
113 pdu_type: PduType::MinefieldResponseNack,
114 protocol_family: ProtocolFamily::Minefield,
115 fields: {
116 pub minefield_id: EntityId,
117 pub requesting_entity_id: EntityId,
118 pub request_id: u8,
119 pub number_of_missing_pdus: u8,
120 pub missing_pdu_sequence_numbers: Vec<u64>,
121 }
122 }
123}
124
125#[cfg(test)]
126mod tests {
127 use super::*;
128 use crate::common::{constants::BITS_PER_BYTE, pdu::Pdu};
129 use bytes::BytesMut;
130
131 mod minefield_state_pdu_tests {
132 use super::*;
133
134 #[test]
135 fn cast_to_any() {
136 let pdu = MinefieldStatePdu::new();
137 let any_pdu = pdu.as_any();
138
139 assert!(any_pdu.is::<MinefieldStatePdu>());
140 }
141
142 #[test]
143 fn serialize_then_deserialize() {
144 let mut pdu = MinefieldStatePdu::new();
145 let mut serialize_buf = BytesMut::new();
146 let _ = pdu.serialize(&mut serialize_buf);
147
148 let mut deserialize_buf = serialize_buf.freeze();
149 let new_pdu = MinefieldStatePdu::deserialize(&mut deserialize_buf).unwrap_or_default();
150 assert_eq!(new_pdu.header, pdu.header);
151 }
152
153 #[test]
154 fn check_default_pdu_length() {
155 const DEFAULT_LENGTH: u16 = 576 / BITS_PER_BYTE;
156 let pdu = MinefieldStatePdu::new();
157 assert_eq!(pdu.header().length, DEFAULT_LENGTH);
158 }
159 }
160
161 mod minefield_query_pdu_tests {
162 use super::*;
163
164 #[test]
165 fn cast_to_any() {
166 let pdu = MinefieldQueryPdu::new();
167 let any_pdu = pdu.as_any();
168
169 assert!(any_pdu.is::<MinefieldQueryPdu>());
170 }
171
172 #[test]
173 fn serialize_then_deserialize() {
174 let mut pdu = MinefieldQueryPdu::new();
175 let mut serialize_buf = BytesMut::new();
176 let _ = pdu.serialize(&mut serialize_buf);
177
178 let mut deserialize_buf = serialize_buf.freeze();
179 let new_pdu = MinefieldQueryPdu::deserialize(&mut deserialize_buf).unwrap_or_default();
180 assert_eq!(new_pdu.header, pdu.header);
181 }
182
183 #[test]
184 fn check_default_pdu_length() {
185 const DEFAULT_LENGTH: u16 = 320 / BITS_PER_BYTE;
186 let pdu = MinefieldQueryPdu::new();
187 assert_eq!(pdu.header().length, DEFAULT_LENGTH);
188 }
189 }
190
191 mod minefield_data_pdu_tests {
192 use super::*;
193
194 #[test]
195 fn cast_to_any() {
196 let pdu = MinefieldDataPdu::new();
197 let any_pdu = pdu.as_any();
198
199 assert!(any_pdu.is::<MinefieldDataPdu>());
200 }
201
202 #[test]
203 fn serialize_then_deserialize() {
204 let mut pdu = MinefieldDataPdu::new();
205 let mut serialize_buf = BytesMut::new();
206 let _ = pdu.serialize(&mut serialize_buf);
207
208 let mut deserialize_buf = serialize_buf.freeze();
209 let new_pdu = MinefieldDataPdu::deserialize(&mut deserialize_buf).unwrap_or_default();
210 assert_eq!(new_pdu.header, pdu.header);
211 }
212
213 #[test]
214 fn check_default_pdu_length() {
215 const DEFAULT_LENGTH: u16 = 352 / BITS_PER_BYTE;
216 let pdu = MinefieldDataPdu::new();
217 assert_eq!(pdu.header().length, DEFAULT_LENGTH);
218 }
219 }
220
221 mod minefield_response_nack_pdu_tests {
222 use super::*;
223
224 #[test]
225 fn cast_to_any() {
226 let pdu = MinefieldResponseNackPdu::new();
227 let any_pdu = pdu.as_any();
228
229 assert!(any_pdu.is::<MinefieldResponseNackPdu>());
230 }
231
232 #[test]
233 fn serialize_then_deserialize() {
234 let mut pdu = MinefieldResponseNackPdu::new();
235 let mut serialize_buf = BytesMut::new();
236 let _ = pdu.serialize(&mut serialize_buf);
237
238 let mut deserialize_buf = serialize_buf.freeze();
239 let new_pdu =
240 MinefieldResponseNackPdu::deserialize(&mut deserialize_buf).unwrap_or_default();
241 assert_eq!(new_pdu.header, pdu.header);
242 }
243
244 #[test]
245 fn check_default_pdu_length() {
246 const DEFAULT_LENGTH: u16 = 208 / BITS_PER_BYTE;
247 let pdu = MinefieldResponseNackPdu::new();
248 assert_eq!(pdu.header().length, DEFAULT_LENGTH);
249 }
250 }
251}