open_dis_rust/logistics/
resupply_cancel_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::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
17#[derive(Clone, Debug)]
18/// Implemented according to IEEE 1278.1-2012 ยง7.4.5
19pub struct ResupplyCancelPdu {
20    pub pdu_header: PduHeader,
21    pub receiving_entity_id: EntityId,
22    pub supplying_entity_id: EntityId,
23}
24
25impl Default for ResupplyCancelPdu {
26    /// Creates a default Resupply Cancel PDU with arbitrary receiving and repairing entity IDs
27    ///
28    /// # Examples
29    ///
30    /// Initializing a Resupply Cancel PDU:
31    /// ```
32    /// use open_dis_rust::logistics::resupply_cancel_pdu::ResupplyCancelPdu;
33    /// let resupply_cancel_pdu = ResupplyCancelPdu::default();
34    /// ```
35    ///
36    fn default() -> Self {
37        ResupplyCancelPdu {
38            pdu_header: PduHeader::default(PduType::ResupplyCancel, ProtocolFamily::Logistics, 56),
39            receiving_entity_id: EntityId::default(1),
40            supplying_entity_id: EntityId::default(2),
41        }
42    }
43}
44
45impl Pdu for ResupplyCancelPdu {
46    fn serialize(&mut self, buf: &mut BytesMut) {
47        self.pdu_header.length = u16::try_from(std::mem::size_of_val(self))
48            .expect("The length of the PDU should fit in a u16.");
49        self.pdu_header.serialize(buf);
50        self.receiving_entity_id.serialize(buf);
51        self.supplying_entity_id.serialize(buf);
52    }
53
54    fn deserialize(mut buffer: BytesMut) -> Result<Self, DISError>
55    where
56        Self: Sized,
57    {
58        let pdu_header = PduHeader::deserialize(&mut buffer);
59        if pdu_header.pdu_type == PduType::ResupplyCancel {
60            let receiving_entity_id = EntityId::deserialize(&mut buffer);
61            let supplying_entity_id = EntityId::deserialize(&mut buffer);
62
63            Ok(ResupplyCancelPdu {
64                pdu_header,
65                receiving_entity_id,
66                supplying_entity_id,
67            })
68        } else {
69            Err(DISError::invalid_header(
70                format!(
71                    "Expected PDU type ResupplyCancel, got {:?}",
72                    pdu_header.pdu_type
73                ),
74                None,
75            ))
76        }
77    }
78
79    fn as_any(&self) -> &dyn Any {
80        self
81    }
82
83    fn deserialize_without_header(
84        mut buffer: BytesMut,
85        pdu_header: PduHeader,
86    ) -> Result<Self, DISError>
87    where
88        Self: Sized,
89    {
90        let receiving_entity_id = EntityId::deserialize(&mut buffer);
91        let supplying_entity_id = EntityId::deserialize(&mut buffer);
92
93        Ok(ResupplyCancelPdu {
94            pdu_header,
95            receiving_entity_id,
96            supplying_entity_id,
97        })
98    }
99}
100
101#[cfg(test)]
102mod tests {
103    use super::ResupplyCancelPdu;
104    use crate::common::{
105        pdu::Pdu,
106        pdu_header::{PduHeader, PduType, ProtocolFamily},
107    };
108    use bytes::BytesMut;
109
110    #[test]
111    fn create_header() {
112        let resupply_cancel_pdu = ResupplyCancelPdu::default();
113        let pdu_header =
114            PduHeader::default(PduType::ResupplyCancel, ProtocolFamily::Logistics, 448 / 8);
115
116        assert_eq!(
117            pdu_header.protocol_version,
118            resupply_cancel_pdu.pdu_header.protocol_version
119        );
120        assert_eq!(
121            pdu_header.exercise_id,
122            resupply_cancel_pdu.pdu_header.exercise_id
123        );
124        assert_eq!(pdu_header.pdu_type, resupply_cancel_pdu.pdu_header.pdu_type);
125        assert_eq!(
126            pdu_header.protocol_family,
127            resupply_cancel_pdu.pdu_header.protocol_family
128        );
129        assert_eq!(pdu_header.length, resupply_cancel_pdu.pdu_header.length);
130        assert_eq!(
131            pdu_header.status_record,
132            resupply_cancel_pdu.pdu_header.status_record
133        );
134    }
135
136    #[test]
137    fn deserialize_header() {
138        let mut resupply_cancel_pdu = ResupplyCancelPdu::default();
139        let mut buffer = BytesMut::new();
140        resupply_cancel_pdu.serialize(&mut buffer);
141
142        let new_resupply_cancel_pdu = ResupplyCancelPdu::deserialize(buffer).unwrap();
143        assert_eq!(
144            new_resupply_cancel_pdu.pdu_header,
145            resupply_cancel_pdu.pdu_header
146        );
147    }
148}