dis_rs/common/attribute/
model.rs1use crate::common::attribute::builder::AttributeBuilder;
2use crate::common::model::{EntityId, PduBody, SimulationAddress};
3use crate::common::{BodyInfo, Interaction};
4use crate::enumerations::{AttributeActionCode, PduType, ProtocolVersion, VariableRecordType};
5#[cfg(feature = "serde")]
6use serde::{Deserialize, Serialize};
7
8pub const BASE_ATTRIBUTE_BODY_LENGTH: u16 = 20;
9pub const BASE_ATTRIBUTE_RECORD_SET_LENGTH: u16 = 8;
10pub const BASE_ATTRIBUTE_RECORD_LENGTH_OCTETS: u16 = 6;
11
12#[derive(Clone, Debug, Default, PartialEq)]
16#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
17pub struct Attribute {
18 pub originating_simulation_address: SimulationAddress,
19 pub record_pdu_type: PduType,
20 pub record_protocol_version: ProtocolVersion,
21 pub master_attribute_record_type: VariableRecordType,
22 pub action_code: AttributeActionCode,
23 pub attribute_record_sets: Vec<AttributeRecordSet>,
24}
25
26impl Attribute {
27 #[must_use]
28 pub fn builder() -> AttributeBuilder {
29 AttributeBuilder::new()
30 }
31
32 #[must_use]
33 pub fn into_builder(self) -> AttributeBuilder {
34 AttributeBuilder::new_from_body(self)
35 }
36
37 #[must_use]
38 pub fn into_pdu_body(self) -> PduBody {
39 PduBody::Attribute(self)
40 }
41}
42
43impl BodyInfo for Attribute {
44 fn body_length(&self) -> u16 {
45 BASE_ATTRIBUTE_BODY_LENGTH
46 + self
47 .attribute_record_sets
48 .iter()
49 .map(|set| {
50 BASE_ATTRIBUTE_RECORD_SET_LENGTH
51 + set
52 .attribute_records
53 .iter()
54 .map(|record| {
55 BASE_ATTRIBUTE_RECORD_LENGTH_OCTETS
56 + record.specific_fields.len() as u16
57 })
58 .sum::<u16>()
59 })
60 .sum::<u16>()
61 }
62
63 fn body_type(&self) -> PduType {
64 PduType::Attribute
65 }
66}
67
68impl Interaction for Attribute {
69 fn originator(&self) -> Option<&EntityId> {
70 None
71 }
72
73 fn receiver(&self) -> Option<&EntityId> {
74 None
75 }
76}
77
78#[derive(Clone, Debug, PartialEq)]
80#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
81pub struct AttributeRecordSet {
82 pub entity_id: EntityId,
83 pub attribute_records: Vec<AttributeRecord>,
84}
85
86impl Default for AttributeRecordSet {
87 fn default() -> Self {
88 Self::new()
89 }
90}
91
92impl AttributeRecordSet {
93 #[must_use]
94 pub fn new() -> Self {
95 Self {
96 entity_id: EntityId::default(),
97 attribute_records: vec![],
98 }
99 }
100
101 #[must_use]
102 pub fn with_entity_id(mut self, entity_id: EntityId) -> Self {
103 self.entity_id = entity_id;
104 self
105 }
106
107 #[must_use]
108 pub fn with_attribute_records(mut self, attribute_records: Vec<AttributeRecord>) -> Self {
109 self.attribute_records = attribute_records;
110 self
111 }
112
113 #[must_use]
114 pub fn with_attribute_record(mut self, attribute_record: AttributeRecord) -> Self {
115 self.attribute_records.push(attribute_record);
116 self
117 }
118}
119
120#[derive(Clone, Debug, PartialEq)]
122#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
123pub struct AttributeRecord {
124 pub record_type: VariableRecordType,
125 pub specific_fields: Vec<u8>,
126}
127
128impl Default for AttributeRecord {
129 fn default() -> Self {
130 Self::new()
131 }
132}
133
134impl AttributeRecord {
135 #[must_use]
136 pub fn new() -> Self {
137 Self {
138 record_type: VariableRecordType::default(),
139 specific_fields: vec![],
140 }
141 }
142
143 #[must_use]
144 pub fn with_record_type(mut self, record_type: VariableRecordType) -> Self {
145 self.record_type = record_type;
146 self
147 }
148
149 #[must_use]
150 pub fn with_specific_fields(mut self, specific_fields: Vec<u8>) -> Self {
151 self.specific_fields = specific_fields;
152 self
153 }
154}