open_dis_rust/distributed_emissions/
electromagnetic_emissions_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 super::data_types::electromagnetic_emission_system_data::ElectromagneticEmissionSystemData;
11
12use crate::common::{
13    dis_error::DISError,
14    entity_id::EntityId,
15    event_id::EventId,
16    pdu::Pdu,
17    pdu_header::{PduHeader, PduType, ProtocolFamily},
18};
19
20#[derive(Clone, Debug)]
21/// Implemented according to IEEE 1278.1-2012 ยง7.6.2
22pub struct ElectromagneticEmissionsPdu {
23    pub pdu_header: PduHeader,
24    pub emitting_entity_id: EntityId,
25    pub event_id: EventId,
26    pub state_update_indicator: u8,
27    pub number_of_systems: u8,
28    pub padding_for_emissions_pdu: u16,
29    pub systems: Vec<ElectromagneticEmissionSystemData>,
30}
31
32impl Default for ElectromagneticEmissionsPdu {
33    /// Creates a default-initialized Electromagnetic Emissions PDU
34    ///
35    /// # Examples
36    ///
37    /// Initializing an Electromagnetic Emissions PDU:
38    /// ```
39    /// use open_dis_rust::distributed_emissions::electromagnetic_emissions_pdu::ElectromagneticEmissionsPdu;
40    /// let mut electromagnetic_emissions_pdu = ElectromagneticEmissionsPdu::default();
41    /// ```
42    ///
43    fn default() -> Self {
44        ElectromagneticEmissionsPdu {
45            pdu_header: PduHeader::default(
46                PduType::ElectromagneticEmission,
47                ProtocolFamily::DistributedEmissionRegeneration,
48                31,
49            ),
50            emitting_entity_id: EntityId::default(1),
51            event_id: EventId::default(1),
52            state_update_indicator: 0,
53            number_of_systems: 1,
54            padding_for_emissions_pdu: 0,
55            systems: vec![ElectromagneticEmissionSystemData::default()],
56        }
57    }
58}
59
60impl Pdu for ElectromagneticEmissionsPdu {
61    /// Serialize contents of `ElectromagneticEmissionsPdu` into `BytesMut` buffer
62    fn serialize(&mut self, buf: &mut BytesMut) {
63        self.pdu_header.length = u16::try_from(std::mem::size_of_val(self))
64            .expect("The length of the PDU should fit in a u16.");
65        self.pdu_header.serialize(buf);
66        self.emitting_entity_id.serialize(buf);
67        self.event_id.serialize(buf);
68        buf.put_u8(self.state_update_indicator);
69        buf.put_u8(self.number_of_systems);
70        buf.put_u16(self.padding_for_emissions_pdu);
71        for i in 0..self.number_of_systems {
72            self.systems[i as usize].serialize(buf);
73        }
74    }
75
76    /// Deserialize bytes from `BytesMut` buffer and interpret as `ElectromagneticEmissionsPdu`
77    fn deserialize(mut buffer: BytesMut) -> Result<Self, DISError>
78    where
79        Self: Sized,
80    {
81        let pdu_header = PduHeader::deserialize(&mut buffer);
82        if pdu_header.pdu_type == PduType::ElectromagneticEmission {
83            let emitting_entity_id = EntityId::deserialize(&mut buffer);
84            let event_id = EventId::deserialize(&mut buffer);
85            let state_update_indicator = buffer.get_u8();
86            let number_of_systems = buffer.get_u8();
87            let padding_for_emissions_pdu = buffer.get_u16();
88            let mut systems: Vec<ElectromagneticEmissionSystemData> = vec![];
89            for _i in 0..number_of_systems {
90                systems.push(ElectromagneticEmissionSystemData::deserialize(&mut buffer));
91            }
92
93            Ok(ElectromagneticEmissionsPdu {
94                pdu_header,
95                emitting_entity_id,
96                event_id,
97                state_update_indicator,
98                number_of_systems,
99                padding_for_emissions_pdu,
100                systems,
101            })
102        } else {
103            Err(DISError::invalid_header(
104                format!(
105                    "Expected PDU type ElectromagneticEmissions, got {:?}",
106                    pdu_header.pdu_type
107                ),
108                None,
109            ))
110        }
111    }
112
113    /// Treat `ElectromagneticEmissionsPdu` as Any type
114    fn as_any(&self) -> &dyn Any {
115        self
116    }
117
118    /// Deserialize bytes from `BytesMut` buffer, but assume PDU header exists already
119    fn deserialize_without_header(
120        mut buffer: BytesMut,
121        pdu_header: PduHeader,
122    ) -> Result<Self, DISError>
123    where
124        Self: Sized,
125    {
126        let emitting_entity_id = EntityId::deserialize(&mut buffer);
127        let event_id = EventId::deserialize(&mut buffer);
128        let state_update_indicator = buffer.get_u8();
129        let number_of_systems = buffer.get_u8();
130        let padding_for_emissions_pdu = buffer.get_u16();
131        let mut systems: Vec<ElectromagneticEmissionSystemData> = vec![];
132        for _i in 0..number_of_systems {
133            systems.push(ElectromagneticEmissionSystemData::deserialize(&mut buffer));
134        }
135
136        Ok(ElectromagneticEmissionsPdu {
137            pdu_header,
138            emitting_entity_id,
139            event_id,
140            state_update_indicator,
141            number_of_systems,
142            padding_for_emissions_pdu,
143            systems,
144        })
145    }
146}
147#[cfg(test)]
148mod tests {
149    use super::ElectromagneticEmissionsPdu;
150    use crate::common::{
151        pdu::Pdu,
152        pdu_header::{PduHeader, PduType, ProtocolFamily},
153    };
154    use bytes::BytesMut;
155
156    #[test]
157    fn create_header() {
158        let electromagnetic_emissions_pdu = ElectromagneticEmissionsPdu::default();
159        let pdu_header = PduHeader::default(
160            PduType::ElectromagneticEmission,
161            ProtocolFamily::DistributedEmissionRegeneration,
162            31,
163        );
164
165        assert_eq!(
166            pdu_header.protocol_version,
167            electromagnetic_emissions_pdu.pdu_header.protocol_version
168        );
169        assert_eq!(
170            pdu_header.exercise_id,
171            electromagnetic_emissions_pdu.pdu_header.exercise_id
172        );
173        assert_eq!(
174            pdu_header.pdu_type,
175            electromagnetic_emissions_pdu.pdu_header.pdu_type
176        );
177        assert_eq!(
178            pdu_header.protocol_family,
179            electromagnetic_emissions_pdu.pdu_header.protocol_family
180        );
181        assert_eq!(
182            pdu_header.length,
183            electromagnetic_emissions_pdu.pdu_header.length
184        );
185        assert_eq!(
186            pdu_header.status_record,
187            electromagnetic_emissions_pdu.pdu_header.status_record
188        );
189    }
190
191    #[test]
192    fn cast_to_any() {
193        let electromagnetic_emissions_pdu = ElectromagneticEmissionsPdu::default();
194        let any_pdu = electromagnetic_emissions_pdu.as_any();
195
196        assert!(any_pdu.is::<ElectromagneticEmissionsPdu>());
197    }
198
199    #[test]
200    fn deserialize_header() {
201        let mut electromagnetic_emissions_pdu = ElectromagneticEmissionsPdu::default();
202        let mut buffer = BytesMut::new();
203        electromagnetic_emissions_pdu.serialize(&mut buffer);
204
205        let new_electromagnetic_emissions_pdu =
206            ElectromagneticEmissionsPdu::deserialize(buffer).unwrap();
207        assert_eq!(
208            new_electromagnetic_emissions_pdu.pdu_header,
209            electromagnetic_emissions_pdu.pdu_header
210        );
211    }
212}