1use crate::{
9 common::{
10 GenericHeader, SerializedLength,
11 data_types::{
12 ClockTime, EntityCoordinateVector, EntityId, EntityType, EventId, LinearVelocity,
13 VariableParameter, WorldCoordinate, directed_energy_damage::DirectedEnergyDamage,
14 munition_descriptor::MunitionDescriptor,
15 },
16 enums::{DEFirePulseShape, DetonationResult, PduType, ProtocolFamily},
17 pdu::Pdu,
18 pdu_header::PduHeader,
19 },
20 define_pdu,
21};
22
23define_pdu! {
24 #[derive(Debug)]
25 pub struct FirePdu {
27 header: PduHeader,
28 pdu_type: PduType::Fire,
29 protocol_family: ProtocolFamily::Warfare,
30 fields: {
31 pub firing_entity_id: EntityId,
32 pub target_entity_id: EntityId,
33 pub munition_expendable_id: EntityId,
34 pub event_id: EventId,
35 pub fire_mission_index: u32,
36 pub location_in_world_coordinates: WorldCoordinate,
37 pub descriptor: MunitionDescriptor,
38 pub velocity: LinearVelocity,
39 pub range: f32,
40 }
41 }
42}
43
44define_pdu! {
45 #[derive(Debug)]
46 pub struct DetonationPdu {
48 header: PduHeader,
49 pdu_type: PduType::Detonation,
50 protocol_family: ProtocolFamily::Warfare,
51 fields: {
52 pub firing_entity_id: EntityId,
53 pub target_entity_id: EntityId,
54 pub exploding_entity_id: EntityId,
55 pub event_id: EventId,
56 pub velocity: LinearVelocity,
57 pub location_in_world_coordinates: WorldCoordinate,
58 pub descriptor: MunitionDescriptor,
59 pub location_in_entitys_coordinates: EntityCoordinateVector,
60 pub detonation_result: DetonationResult,
61 pub number_of_variable_parameters: u8,
62 padding: u16,
63 pub variable_parameters: Vec<VariableParameter>,
64 }
65 }
66}
67
68define_pdu! {
69 #[derive(Debug)]
70 pub struct DirectedEnergyFirePdu {
72 header: PduHeader,
73 pdu_type: PduType::DirectedEnergyFire,
74 protocol_family: ProtocolFamily::Warfare,
75 fields: {
76 pub firing_entity_id: EntityId,
77 pub event_id: EventId,
78 pub munition_type: EntityType,
79 pub shot_start_time: ClockTime,
80 pub cumulative_shot_time: f32,
81 pub aperture_emitter_location: EntityCoordinateVector,
82 pub aperture_diameter: f32,
83 pub wavelength: f32,
84 padding: u32,
85 pub pulse_repetition_frequency: f32,
86 pub pulse_width: f32,
87 pub flags: u16,
88 pub pulse_shape: DEFirePulseShape,
89 padding2: u8,
90 padding3: u32,
91 padding4: u16,
92 pub number_of_de_records: u16,
93 pub damage_descriptions: Vec<DirectedEnergyDamage>,
94 }
95 }
96}
97
98define_pdu! {
99 #[derive(Debug)]
100 pub struct EntityDamageStatusPdu {
102 header: PduHeader,
103 pdu_type: PduType::EntityDamageStatus,
104 protocol_family: ProtocolFamily::Warfare,
105 fields: {
106 pub damaged_entity_id: EntityId,
107 padding: u16,
108 padding2: u16,
109 pub number_of_damage_descriptions: u16,
110 pub damage_descriptions: Vec<DirectedEnergyDamage>,
111 }
112 }
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118 use crate::common::{constants::BITS_PER_BYTE, pdu::Pdu};
119 use bytes::BytesMut;
120
121 mod fire_pdu_tests {
122 use super::*;
123
124 #[test]
125 fn cast_to_any() {
126 let fire_pdu = FirePdu::new();
127 let any_pdu = fire_pdu.as_any();
128
129 assert!(any_pdu.is::<FirePdu>());
130 }
131
132 #[test]
133 fn serialize_then_deserialize() {
134 let mut pdu = FirePdu::new();
135 let mut serialize_buf = BytesMut::new();
136 let _ = pdu.serialize(&mut serialize_buf);
137
138 let mut deserialize_buf = serialize_buf.freeze();
139 let new_pdu = FirePdu::deserialize(&mut deserialize_buf).unwrap_or_default();
140 assert_eq!(new_pdu.header, pdu.header);
141 }
142
143 #[test]
144 fn check_default_pdu_length() {
145 const DEFAULT_LENGTH: u16 = 768 / 8;
146 let pdu = FirePdu::new();
147 assert_eq!(pdu.header().length, DEFAULT_LENGTH);
148 }
149 }
150
151 mod detonation_pdu_tests {
152 use super::*;
153
154 #[test]
155 fn cast_to_any() {
156 let detonation_pdu = DetonationPdu::new();
157 let any_pdu = detonation_pdu.as_any();
158
159 assert!(any_pdu.is::<DetonationPdu>());
160 }
161
162 #[test]
163 fn serialize_then_deserialize() {
164 let mut pdu = DetonationPdu::new();
165 let mut serialize_buf = BytesMut::new();
166 let _ = pdu.serialize(&mut serialize_buf);
167
168 let mut deserialize_buf = serialize_buf.freeze();
169 let new_pdu = DetonationPdu::deserialize(&mut deserialize_buf).unwrap_or_default();
170 assert_eq!(new_pdu.header, pdu.header);
171 }
172
173 #[test]
174 fn check_default_pdu_length() {
175 const DEFAULT_LENGTH: u16 = 832 / BITS_PER_BYTE;
176 let pdu = DetonationPdu::new();
177 assert_eq!(pdu.header().length, DEFAULT_LENGTH);
178 }
179 }
180
181 mod directed_energy_fire_pdu_tests {
182 use super::*;
183
184 #[test]
185 fn cast_to_any() {
186 let pdu = DirectedEnergyFirePdu::new();
187 let any_pdu = pdu.as_any();
188
189 assert!(any_pdu.is::<DirectedEnergyFirePdu>());
190 }
191
192 #[test]
193 fn serialize_then_deserialize() {
194 let mut pdu = DirectedEnergyFirePdu::new();
195 let mut serialize_buf = BytesMut::new();
196 let _ = pdu.serialize(&mut serialize_buf);
197
198 let mut deserialize_buf = serialize_buf.freeze();
199 let new_pdu =
200 DirectedEnergyFirePdu::deserialize(&mut deserialize_buf).unwrap_or_default();
201 assert_eq!(new_pdu.header, pdu.header);
202 }
203
204 #[test]
205 fn check_default_pdu_length() {
206 const DEFAULT_LENGTH: u16 = 704 / BITS_PER_BYTE;
207 let pdu = DirectedEnergyFirePdu::new();
208 assert_eq!(pdu.header().length, DEFAULT_LENGTH);
209 }
210 }
211
212 mod entity_damage_status_pdu_tests {
213 use super::*;
214
215 #[test]
216 fn cast_to_any() {
217 let entity_damage_status_pdu = EntityDamageStatusPdu::new();
218 let any_pdu = entity_damage_status_pdu.as_any();
219
220 assert!(any_pdu.is::<EntityDamageStatusPdu>());
221 }
222
223 #[test]
224 fn serialize_then_deserialize() {
225 let mut pdu = EntityDamageStatusPdu::new();
226 let mut serialize_buf = BytesMut::new();
227 let _ = pdu.serialize(&mut serialize_buf);
228
229 let mut deserialize_buf = serialize_buf.freeze();
230 let new_pdu =
231 EntityDamageStatusPdu::deserialize(&mut deserialize_buf).unwrap_or_default();
232 assert_eq!(new_pdu.header, pdu.header);
233 }
234
235 #[test]
236 fn check_default_pdu_length() {
237 const DEFAULT_LENGTH: u16 = 192 / 8;
238 let pdu = EntityDamageStatusPdu::new();
239 assert_eq!(pdu.header().length, DEFAULT_LENGTH);
240 }
241 }
242}