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::decode(&mut buffer);
56        if pdu_header.pdu_type == PduType::RemoveEntity {
57            let originating_entity_id = EntityId::decode(&mut buffer);
58            let receiving_entity_id = EntityId::decode(&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::InvalidDISHeader)
69        }
70    }
71
72    fn as_any(&self) -> &dyn Any {
73        self
74    }
75
76    fn deserialize_without_header(
77        mut buffer: BytesMut,
78        pdu_header: PduHeader,
79    ) -> Result<Self, DISError>
80    where
81        Self: Sized,
82    {
83        let originating_entity_id = EntityId::decode(&mut buffer);
84        let receiving_entity_id = EntityId::decode(&mut buffer);
85        let request_id = buffer.get_u32();
86
87        Ok(RemoveEntityPdu {
88            pdu_header,
89            originating_entity_id,
90            receiving_entity_id,
91            request_id,
92        })
93    }
94}
95
96#[cfg(test)]
97mod tests {
98    use super::RemoveEntityPdu;
99    use crate::common::{
100        pdu::Pdu,
101        pdu_header::{PduHeader, PduType, ProtocolFamily},
102    };
103    use bytes::BytesMut;
104
105    #[test]
106    fn create_header() {
107        let remove_entity_pdu = RemoveEntityPdu::default();
108        let pdu_header = PduHeader::default(
109            PduType::RemoveEntity,
110            ProtocolFamily::SimulationManagement,
111            448 / 8,
112        );
113
114        assert_eq!(
115            pdu_header.protocol_version,
116            remove_entity_pdu.pdu_header.protocol_version
117        );
118        assert_eq!(
119            pdu_header.exercise_id,
120            remove_entity_pdu.pdu_header.exercise_id
121        );
122        assert_eq!(pdu_header.pdu_type, remove_entity_pdu.pdu_header.pdu_type);
123        assert_eq!(
124            pdu_header.protocol_family,
125            remove_entity_pdu.pdu_header.protocol_family
126        );
127        assert_eq!(pdu_header.length, remove_entity_pdu.pdu_header.length);
128        assert_eq!(pdu_header.padding, remove_entity_pdu.pdu_header.padding);
129    }
130
131    #[test]
132    fn deserialize_header() {
133        let mut remove_entity_pdu = RemoveEntityPdu::default();
134        let mut buffer = BytesMut::new();
135        remove_entity_pdu.serialize(&mut buffer);
136
137        let new_remove_entity_pdu = RemoveEntityPdu::deserialize(buffer).unwrap();
138        assert_eq!(
139            new_remove_entity_pdu.pdu_header,
140            remove_entity_pdu.pdu_header
141        );
142    }
143}