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