open_dis_rust/logistics/
resupply_offer_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::supply_quantity::SupplyQuantity;
18
19#[derive(Clone, Debug)]
20pub struct ResupplyOfferPdu {
22 pub pdu_header: PduHeader,
23 pub receiving_entity_id: EntityId,
24 pub supplying_entity_id: EntityId,
25 pub number_of_supply_types: u8,
26 pub padding1: i16,
27 pub padding2: i8,
28 pub supplies: Vec<SupplyQuantity>,
29}
30
31impl Default for ResupplyOfferPdu {
32 fn default() -> Self {
43 ResupplyOfferPdu {
44 pdu_header: PduHeader::default(PduType::ResupplyOffer, ProtocolFamily::Logistics, 56),
45 receiving_entity_id: EntityId::default(1),
46 supplying_entity_id: EntityId::default(2),
47 number_of_supply_types: 0,
48 padding1: 0,
49 padding2: 0,
50 supplies: vec![],
51 }
52 }
53}
54
55impl Pdu for ResupplyOfferPdu {
56 fn serialize(&mut self, buf: &mut BytesMut) {
57 self.pdu_header.length = u16::try_from(std::mem::size_of_val(self))
58 .expect("The length of the PDU should fit in a u16.");
59 self.pdu_header.serialize(buf);
60 self.receiving_entity_id.serialize(buf);
61 self.supplying_entity_id.serialize(buf);
62 buf.put_u8(self.number_of_supply_types);
63 buf.put_i16(self.padding1);
64 buf.put_i8(self.padding2);
65 for i in 0..self.supplies.len() {
66 self.supplies[i].serialize(buf);
67 }
68 }
69
70 fn deserialize(mut buffer: BytesMut) -> Result<Self, DISError>
71 where
72 Self: Sized,
73 {
74 let pdu_header = PduHeader::deserialize(&mut buffer);
75 if pdu_header.pdu_type == PduType::ResupplyOffer {
76 let receiving_entity_id = EntityId::deserialize(&mut buffer);
77 let supplying_entity_id = EntityId::deserialize(&mut buffer);
78 let number_of_supply_types = buffer.get_u8();
79 let padding1 = buffer.get_i16();
80 let padding2 = buffer.get_i8();
81 let mut supplies: Vec<SupplyQuantity> = vec![];
82 for _i in 0..number_of_supply_types {
83 supplies.push(SupplyQuantity::deserialize(&mut buffer));
84 }
85
86 Ok(ResupplyOfferPdu {
87 pdu_header,
88 receiving_entity_id,
89 supplying_entity_id,
90 number_of_supply_types,
91 padding1,
92 padding2,
93 supplies,
94 })
95 } else {
96 Err(DISError::invalid_header(
97 format!(
98 "Expected PDU type ResupplyOffer, got {:?}",
99 pdu_header.pdu_type
100 ),
101 None,
102 ))
103 }
104 }
105
106 fn as_any(&self) -> &dyn Any {
107 self
108 }
109
110 fn deserialize_without_header(
111 mut buffer: BytesMut,
112 pdu_header: PduHeader,
113 ) -> Result<Self, DISError>
114 where
115 Self: Sized,
116 {
117 let receiving_entity_id = EntityId::deserialize(&mut buffer);
118 let supplying_entity_id = EntityId::deserialize(&mut buffer);
119 let number_of_supply_types = buffer.get_u8();
120 let padding1 = buffer.get_i16();
121 let padding2 = buffer.get_i8();
122 let mut supplies: Vec<SupplyQuantity> = vec![];
123 for _i in 0..number_of_supply_types {
124 supplies.push(SupplyQuantity::deserialize(&mut buffer));
125 }
126
127 Ok(ResupplyOfferPdu {
128 pdu_header,
129 receiving_entity_id,
130 supplying_entity_id,
131 number_of_supply_types,
132 padding1,
133 padding2,
134 supplies,
135 })
136 }
137}
138
139#[cfg(test)]
140mod tests {
141 use super::ResupplyOfferPdu;
142 use crate::common::{
143 pdu::Pdu,
144 pdu_header::{PduHeader, PduType, ProtocolFamily},
145 };
146 use bytes::BytesMut;
147
148 #[test]
149 fn create_header() {
150 let resupply_offer_pdu = ResupplyOfferPdu::default();
151 let pdu_header =
152 PduHeader::default(PduType::ResupplyOffer, ProtocolFamily::Logistics, 448 / 8);
153
154 assert_eq!(
155 pdu_header.protocol_version,
156 resupply_offer_pdu.pdu_header.protocol_version
157 );
158 assert_eq!(
159 pdu_header.exercise_id,
160 resupply_offer_pdu.pdu_header.exercise_id
161 );
162 assert_eq!(pdu_header.pdu_type, resupply_offer_pdu.pdu_header.pdu_type);
163 assert_eq!(
164 pdu_header.protocol_family,
165 resupply_offer_pdu.pdu_header.protocol_family
166 );
167 assert_eq!(pdu_header.length, resupply_offer_pdu.pdu_header.length);
168 assert_eq!(
169 pdu_header.status_record,
170 resupply_offer_pdu.pdu_header.status_record
171 );
172 }
173
174 #[test]
175 fn deserialize_header() {
176 let mut resupply_offer_pdu = ResupplyOfferPdu::default();
177 let mut buffer = BytesMut::new();
178 resupply_offer_pdu.serialize(&mut buffer);
179
180 let new_resupply_offer_pdu = ResupplyOfferPdu::deserialize(buffer).unwrap();
181 assert_eq!(
182 new_resupply_offer_pdu.pdu_header,
183 resupply_offer_pdu.pdu_header
184 );
185 }
186}