open_dis_rust/warfare/
entity_damage_status_pdu.rs1use bytes::{Buf, BufMut, BytesMut};
8use std::any::Any;
9
10use crate::common::{
11 dis_error::DISError,
12 entity_id::EntityId,
13 pdu::Pdu,
14 pdu_header::{PduHeader, PduType, ProtocolFamily},
15};
16
17use super::data_types::directed_energy_damage::DirectedEnergyDamage;
18
19#[derive(Clone, Debug)]
20pub struct EntityDamageStatusPdu {
22 pub pdu_header: PduHeader,
23 pub firing_entity_id: EntityId,
24 pub target_entity_id: EntityId,
25 pub damaged_entity_id: EntityId,
26 pub padding1: u16,
27 pub padding2: u16,
28 pub number_of_damage_descriptions: u16,
29 pub damage_descriptions: Vec<DirectedEnergyDamage>,
30}
31
32impl Default for EntityDamageStatusPdu {
33 fn default() -> Self {
44 EntityDamageStatusPdu {
45 pdu_header: PduHeader::default(
46 PduType::EntityDamageStatus,
47 ProtocolFamily::Warfare,
48 56,
49 ),
50 firing_entity_id: EntityId::default(1),
51 target_entity_id: EntityId::default(2),
52 damaged_entity_id: EntityId::default(3),
53 padding1: 0,
54 padding2: 0,
55 number_of_damage_descriptions: 0,
56 damage_descriptions: vec![],
57 }
58 }
59}
60
61impl Pdu for EntityDamageStatusPdu {
62 fn serialize(&mut self, buf: &mut BytesMut) {
63 self.pdu_header.length = u16::try_from(std::mem::size_of_val(self))
64 .expect("The length of the PDU should fit in a u16.");
65 self.pdu_header.serialize(buf);
66 self.firing_entity_id.serialize(buf);
67 self.target_entity_id.serialize(buf);
68 self.damaged_entity_id.serialize(buf);
69 buf.put_u16(self.padding1);
70 buf.put_u16(self.padding2);
71 buf.put_u16(self.number_of_damage_descriptions);
72 for i in 0..self.damage_descriptions.len() {
73 self.damage_descriptions[i].serialize(buf);
74 }
75 }
76
77 fn deserialize(mut buffer: BytesMut) -> Result<Self, DISError>
78 where
79 Self: Sized,
80 {
81 let pdu_header = PduHeader::deserialize(&mut buffer);
82 if pdu_header.pdu_type == PduType::EntityDamageStatus {
83 let firing_entity_id = EntityId::deserialize(&mut buffer);
84 let target_entity_id = EntityId::deserialize(&mut buffer);
85 let damaged_entity_id = EntityId::deserialize(&mut buffer);
86 let padding1 = buffer.get_u16();
87 let padding2 = buffer.get_u16();
88 let number_of_damage_descriptions = buffer.get_u16();
89 let damage_descriptions: Vec<DirectedEnergyDamage> = vec![];
90 Ok(EntityDamageStatusPdu {
91 pdu_header,
92 firing_entity_id,
93 target_entity_id,
94 damaged_entity_id,
95 padding1,
96 padding2,
97 number_of_damage_descriptions,
98 damage_descriptions,
99 })
100 } else {
101 Err(DISError::invalid_header(
102 format!(
103 "Expected PDU type EntityDamageStatus, got {:?}",
104 pdu_header.pdu_type
105 ),
106 None,
107 ))
108 }
109 }
110
111 fn as_any(&self) -> &dyn Any {
112 self
113 }
114
115 fn deserialize_without_header(
116 mut buffer: BytesMut,
117 pdu_header: PduHeader,
118 ) -> Result<Self, DISError>
119 where
120 Self: Sized,
121 {
122 let firing_entity_id = EntityId::deserialize(&mut buffer);
123 let target_entity_id = EntityId::deserialize(&mut buffer);
124 let damaged_entity_id = EntityId::deserialize(&mut buffer);
125 let padding1 = buffer.get_u16();
126 let padding2 = buffer.get_u16();
127 let number_of_damage_descriptions = buffer.get_u16();
128 let damage_descriptions: Vec<DirectedEnergyDamage> = vec![];
129 Ok(EntityDamageStatusPdu {
130 pdu_header,
131 firing_entity_id,
132 target_entity_id,
133 damaged_entity_id,
134 padding1,
135 padding2,
136 number_of_damage_descriptions,
137 damage_descriptions,
138 })
139 }
140}
141
142#[cfg(test)]
143mod tests {
144 use super::EntityDamageStatusPdu;
145 use crate::common::{
146 pdu::Pdu,
147 pdu_header::{PduHeader, PduType, ProtocolFamily},
148 };
149 use bytes::BytesMut;
150
151 #[test]
152 fn create_header() {
153 let entity_damage_status_pdu = EntityDamageStatusPdu::default();
154 let pdu_header = PduHeader::default(
155 PduType::EntityDamageStatus,
156 ProtocolFamily::Warfare,
157 448 / 8,
158 );
159
160 assert_eq!(
161 pdu_header.protocol_version,
162 entity_damage_status_pdu.pdu_header.protocol_version
163 );
164 assert_eq!(
165 pdu_header.exercise_id,
166 entity_damage_status_pdu.pdu_header.exercise_id
167 );
168 assert_eq!(
169 pdu_header.pdu_type,
170 entity_damage_status_pdu.pdu_header.pdu_type
171 );
172 assert_eq!(
173 pdu_header.protocol_family,
174 entity_damage_status_pdu.pdu_header.protocol_family
175 );
176 assert_eq!(
177 pdu_header.length,
178 entity_damage_status_pdu.pdu_header.length
179 );
180 assert_eq!(
181 pdu_header.status_record,
182 entity_damage_status_pdu.pdu_header.status_record
183 );
184 }
185
186 #[test]
187 fn deserialize_header() {
188 let mut entity_damage_status_pdu = EntityDamageStatusPdu::default();
189 let mut buffer = BytesMut::new();
190 entity_damage_status_pdu.serialize(&mut buffer);
191
192 let new_entity_damage_status_pdu = EntityDamageStatusPdu::deserialize(buffer).unwrap();
193 assert_eq!(
194 new_entity_damage_status_pdu.pdu_header,
195 entity_damage_status_pdu.pdu_header
196 );
197 }
198}