Skip to main content

dis_rs/common/
mod.rs

1pub mod model;
2pub(crate) mod parser;
3pub mod timestamp;
4
5pub mod acknowledge;
6pub mod acknowledge_r;
7pub mod action_request;
8pub mod action_request_r;
9pub mod action_response;
10pub mod action_response_r;
11pub mod aggregate_state;
12pub mod attribute;
13pub mod collision;
14pub mod collision_elastic;
15pub mod comment;
16pub mod comment_r;
17pub mod create_entity;
18pub mod create_entity_r;
19pub mod data;
20pub mod data_query;
21pub mod data_query_r;
22pub mod data_r;
23pub mod designator;
24pub mod detonation;
25pub mod electromagnetic_emission;
26pub mod entity_state;
27pub mod entity_state_update;
28pub mod event_report;
29pub mod event_report_r;
30pub mod fire;
31pub mod iff;
32pub mod is_group_of;
33pub mod is_part_of;
34pub mod other;
35pub mod receiver;
36pub mod record_query_r;
37pub mod record_r;
38pub mod remove_entity;
39pub mod remove_entity_r;
40pub mod repair_complete;
41pub mod repair_response;
42pub mod resupply_cancel;
43pub mod resupply_offer;
44pub mod resupply_received;
45pub mod sees;
46pub mod service_request;
47pub mod set_data;
48pub mod set_data_r;
49pub mod set_record_r;
50pub mod signal;
51pub mod start_resume;
52pub mod start_resume_r;
53pub mod stop_freeze;
54pub mod stop_freeze_r;
55pub mod transfer_ownership;
56pub mod transmitter;
57pub mod underwater_acoustic;
58
59pub mod errors;
60mod writer;
61
62use crate::common::errors::DisError;
63use crate::common::model::Pdu;
64use crate::common::parser::parse_multiple_pdu;
65use crate::enumerations::{PduType, ProtocolVersion};
66use crate::model::PduBody;
67use alloc::vec::Vec;
68use bytes::BytesMut;
69
70#[allow(dead_code)]
71pub enum SupportedVersion {
72    V6,
73    V7,
74    Unsupported,
75}
76
77impl From<ProtocolVersion> for SupportedVersion {
78    fn from(version: ProtocolVersion) -> Self {
79        match version {
80            ProtocolVersion::IEEE1278_1A1998 => SupportedVersion::V6,
81            ProtocolVersion::IEEE1278_12012 => SupportedVersion::V7,
82            _ => SupportedVersion::Unsupported,
83        }
84    }
85}
86
87/// Returns a list of all `ProtocolVersion`s supported by the crate.
88#[must_use]
89pub fn supported_protocol_versions() -> &'static [ProtocolVersion] {
90    &[
91        ProtocolVersion::IEEE1278_1A1998,
92        ProtocolVersion::IEEE1278_12012,
93    ]
94}
95
96/// Trait for PduBody-s to build and convert specific PDU types
97pub trait BodyRaw {
98    type Builder;
99
100    #[must_use]
101    fn builder() -> Self::Builder;
102
103    #[must_use]
104    fn into_builder(self) -> Self::Builder;
105
106    #[must_use]
107    fn into_pdu_body(self) -> PduBody;
108}
109
110impl<T: BodyRaw> From<T> for PduBody {
111    #[inline]
112    fn from(value: T) -> Self {
113        value.into_pdu_body()
114    }
115}
116
117/// Trait for PduBody-s to query basic information, typically used in the header
118pub trait BodyInfo {
119    fn body_length(&self) -> u16;
120    fn body_type(&self) -> PduType;
121}
122
123/// Trait for PDUs to implement whether an interaction between one or two
124/// entities happens. Used to generically query the originating ``EntityId`` and (optional) receiving ``EntityId`` of
125/// the interaction. When a PDU has no interaction, both the originator and receiver are ``None``.
126pub trait Interaction {
127    fn originator(&self) -> Option<&model::EntityId>;
128    fn receiver(&self) -> Option<&model::EntityId>;
129}
130
131/// Trait that implements writing a `PduBody` to a buffer
132/// based on the protocol version of the PDU.
133/// Returns the number of bytes written to the buffer.
134pub trait SerializePdu {
135    fn serialize_pdu(&self, version: SupportedVersion, buf: &mut BytesMut) -> u16;
136}
137
138/// Trait that implements writing data structures to a buffer.
139/// This serialize must be independent of protocol version differences for the data structure.
140/// Returns the number of bytes written to the buffer.
141pub trait Serialize {
142    fn serialize(&self, buf: &mut BytesMut) -> u16;
143}
144
145/// Parses the contents of the input, determining the DIS version by itself.
146/// This function tries to parse as many PDUs as there are in the buffer,
147/// assuming there are only complete PDUs present in the input.
148///
149/// Assumes there will only be a single DIS version of PDUs in a buffer (packet).
150///
151/// # Errors
152/// Returns a `DisError` when parsing fails
153pub fn parse(input: &[u8]) -> Result<Vec<Pdu>, DisError> {
154    parse_multiple_pdu(input)
155}
156
157/// Parses the contents of the input as DIS version 6.
158/// This function tries to parse as many PDUs as there are in the buffer,
159/// assuming there are only complete PDUs present in the input.
160///
161/// This function will filter out any non-v6 PDUs in a buffer (packet).
162///
163/// # Errors
164/// Returns a `DisError` when parsing fails
165pub fn parse_v6(input: &[u8]) -> Result<Vec<Pdu>, DisError> {
166    let pdus = parse_multiple_pdu(input)?
167        .into_iter()
168        .filter(|pdu| pdu.header.protocol_version == ProtocolVersion::IEEE1278_1A1998)
169        .collect();
170    Ok(pdus)
171}
172
173/// Parses the contents of the input as DIS version 7.
174/// This function tries to parse as many PDUs as there are in the buffer,
175/// assuming there are only complete PDUs present in the input.
176///
177/// This function will filter out any non-v7 PDUs in a buffer (packet).
178///
179/// # Errors
180/// Returns a `DisError` when parsing fails
181pub fn parse_v7(input: &[u8]) -> Result<Vec<Pdu>, DisError> {
182    let pdus = parse_multiple_pdu(input)?
183        .into_iter()
184        .filter(|pdu| pdu.header.protocol_version == ProtocolVersion::IEEE1278_12012)
185        .collect();
186    Ok(pdus)
187}