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