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