open_dis_rust/logistics/
resupply_received_pdu.rs

1//     open-dis-rust - Rust implementation of the IEEE 1278.1-2012 Distributed Interactive
2//                     Simulation (DIS) application protocol
3//     Copyright (C) 2023 Cameron Howell
4//
5//     Licensed under the BSD 2-Clause License
6
7use 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)]
20/// Implemented according to IEEE 1278.1-2012 ยง7.4.4
21pub struct ResupplyReceivedPdu {
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 ResupplyReceivedPdu {
32    /// Creates a default Resupply Received PDU with arbitrary receiving and supplying entity IDs
33    ///
34    /// # Examples
35    ///
36    /// Initializing a Resupply Received PDU:
37    /// ```
38    /// use open_dis_rust::logistics::resupply_received_pdu::ResupplyReceivedPdu;
39    /// let resupply_received_pdu = ResupplyReceivedPdu::default();
40    /// ```
41    ///
42    fn default() -> Self {
43        ResupplyReceivedPdu {
44            pdu_header: PduHeader::default(
45                PduType::ResupplyReceived,
46                ProtocolFamily::Logistics,
47                56,
48            ),
49            receiving_entity_id: EntityId::default(1),
50            supplying_entity_id: EntityId::default(2),
51            number_of_supply_types: 0,
52            padding1: 0,
53            padding2: 0,
54            supplies: vec![],
55        }
56    }
57}
58
59impl Pdu for ResupplyReceivedPdu {
60    fn serialize(&mut self, buf: &mut BytesMut) {
61        self.pdu_header.length = u16::try_from(std::mem::size_of_val(self))
62            .expect("The length of the PDU should fit in a u16.");
63        self.pdu_header.serialize(buf);
64        self.receiving_entity_id.serialize(buf);
65        self.supplying_entity_id.serialize(buf);
66        buf.put_u8(self.number_of_supply_types);
67        buf.put_i16(self.padding1);
68        buf.put_i8(self.padding2);
69        for i in 0..self.supplies.len() {
70            self.supplies[i].serialize(buf);
71        }
72    }
73
74    fn deserialize(mut buffer: BytesMut) -> Result<Self, DISError>
75    where
76        Self: Sized,
77    {
78        let pdu_header = PduHeader::deserialize(&mut buffer);
79        if pdu_header.pdu_type == PduType::ResupplyReceived {
80            let receiving_entity_id = EntityId::deserialize(&mut buffer);
81            let supplying_entity_id = EntityId::deserialize(&mut buffer);
82            let number_of_supply_types = buffer.get_u8();
83            let padding1 = buffer.get_i16();
84            let padding2 = buffer.get_i8();
85            let mut supplies: Vec<SupplyQuantity> = vec![];
86            for _i in 0..number_of_supply_types {
87                supplies.push(SupplyQuantity::deserialize(&mut buffer));
88            }
89
90            Ok(ResupplyReceivedPdu {
91                pdu_header,
92                receiving_entity_id,
93                supplying_entity_id,
94                number_of_supply_types,
95                padding1,
96                padding2,
97                supplies,
98            })
99        } else {
100            Err(DISError::invalid_header(
101                format!(
102                    "Expected PDU type ResupplyReceived, got {:?}",
103                    pdu_header.pdu_type
104                ),
105                None,
106            ))
107        }
108    }
109
110    fn as_any(&self) -> &dyn Any {
111        self
112    }
113
114    fn deserialize_without_header(
115        mut buffer: BytesMut,
116        pdu_header: PduHeader,
117    ) -> Result<Self, DISError>
118    where
119        Self: Sized,
120    {
121        let receiving_entity_id = EntityId::deserialize(&mut buffer);
122        let supplying_entity_id = EntityId::deserialize(&mut buffer);
123        let number_of_supply_types = buffer.get_u8();
124        let padding1 = buffer.get_i16();
125        let padding2 = buffer.get_i8();
126        let mut supplies: Vec<SupplyQuantity> = vec![];
127        for _i in 0..number_of_supply_types {
128            supplies.push(SupplyQuantity::deserialize(&mut buffer));
129        }
130
131        Ok(ResupplyReceivedPdu {
132            pdu_header,
133            receiving_entity_id,
134            supplying_entity_id,
135            number_of_supply_types,
136            padding1,
137            padding2,
138            supplies,
139        })
140    }
141}
142
143#[cfg(test)]
144mod tests {
145    use super::ResupplyReceivedPdu;
146    use crate::common::{
147        pdu::Pdu,
148        pdu_header::{PduHeader, PduType, ProtocolFamily},
149    };
150    use bytes::BytesMut;
151
152    #[test]
153    fn create_header() {
154        let resupply_received_pdu = ResupplyReceivedPdu::default();
155        let pdu_header = PduHeader::default(
156            PduType::ResupplyReceived,
157            ProtocolFamily::Logistics,
158            448 / 8,
159        );
160
161        assert_eq!(
162            pdu_header.protocol_version,
163            resupply_received_pdu.pdu_header.protocol_version
164        );
165        assert_eq!(
166            pdu_header.exercise_id,
167            resupply_received_pdu.pdu_header.exercise_id
168        );
169        assert_eq!(
170            pdu_header.pdu_type,
171            resupply_received_pdu.pdu_header.pdu_type
172        );
173        assert_eq!(
174            pdu_header.protocol_family,
175            resupply_received_pdu.pdu_header.protocol_family
176        );
177        assert_eq!(pdu_header.length, resupply_received_pdu.pdu_header.length);
178        assert_eq!(
179            pdu_header.status_record,
180            resupply_received_pdu.pdu_header.status_record
181        );
182    }
183
184    #[test]
185    fn deserialize_header() {
186        let mut resupply_received_pdu = ResupplyReceivedPdu::default();
187        let mut buffer = BytesMut::new();
188        resupply_received_pdu.serialize(&mut buffer);
189
190        let new_resupply_received_pdu = ResupplyReceivedPdu::deserialize(buffer).unwrap();
191        assert_eq!(
192            new_resupply_received_pdu.pdu_header,
193            resupply_received_pdu.pdu_header
194        );
195    }
196}