open_dis_rust/minefield/
minefield_response_nack_pdu.rs1use 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(Clone, Debug)]
17pub struct MinefieldResponseNackPdu {
19 pub pdu_header: PduHeader,
20 pub minefield_id: EntityId,
21 pub requesting_entity_id: EntityId,
22 pub request_id: u8,
23 pub number_of_missing_pdus: u8,
24 pub missing_pdu_sequence_numbers: Vec<u64>,
25}
26
27impl Default for MinefieldResponseNackPdu {
28 fn default() -> Self {
29 MinefieldResponseNackPdu {
30 pdu_header: PduHeader::default(
31 PduType::MinefieldResponseNack,
32 ProtocolFamily::Minefield,
33 56,
34 ),
35 minefield_id: EntityId::default(1),
36 requesting_entity_id: EntityId::default(2),
37 request_id: 0,
38 number_of_missing_pdus: 0,
39 missing_pdu_sequence_numbers: vec![],
40 }
41 }
42}
43
44impl Pdu for MinefieldResponseNackPdu {
45 fn serialize(&mut self, buf: &mut BytesMut) {
46 self.pdu_header.length = u16::try_from(std::mem::size_of_val(self))
47 .expect("The length of the PDU should fit in a u16.");
48 self.pdu_header.serialize(buf);
49 self.minefield_id.serialize(buf);
50 self.requesting_entity_id.serialize(buf);
51 buf.put_u8(self.request_id);
52 buf.put_u8(self.number_of_missing_pdus);
53 for i in 0..self.missing_pdu_sequence_numbers.len() {
54 buf.put_u64(self.missing_pdu_sequence_numbers[i]);
55 }
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::MinefieldResponseNack {
64 let minefield_id = EntityId::deserialize(&mut buffer);
65 let requesting_entity_id = EntityId::deserialize(&mut buffer);
66 let request_id = buffer.get_u8();
67 let number_of_missing_pdus = buffer.get_u8();
68 let mut missing_pdu_sequence_numbers: Vec<u64> = vec![];
69 for _i in 0..number_of_missing_pdus {
70 missing_pdu_sequence_numbers.push(buffer.get_u64());
71 }
72
73 Ok(MinefieldResponseNackPdu {
74 pdu_header,
75 minefield_id,
76 requesting_entity_id,
77 request_id,
78 number_of_missing_pdus,
79 missing_pdu_sequence_numbers,
80 })
81 } else {
82 Err(DISError::invalid_header(
83 format!(
84 "Expected PDU type MinefieldResponseNack, got {:?}",
85 pdu_header.pdu_type
86 ),
87 None,
88 ))
89 }
90 }
91
92 fn as_any(&self) -> &dyn Any {
93 self
94 }
95
96 fn deserialize_without_header(
97 mut buffer: BytesMut,
98 pdu_header: PduHeader,
99 ) -> Result<Self, DISError>
100 where
101 Self: Sized,
102 {
103 let minefield_id = EntityId::deserialize(&mut buffer);
104 let requesting_entity_id = EntityId::deserialize(&mut buffer);
105 let request_id = buffer.get_u8();
106 let number_of_missing_pdus = buffer.get_u8();
107 let mut missing_pdu_sequence_numbers: Vec<u64> = vec![];
108 for _i in 0..number_of_missing_pdus {
109 missing_pdu_sequence_numbers.push(buffer.get_u64());
110 }
111
112 Ok(MinefieldResponseNackPdu {
113 pdu_header,
114 minefield_id,
115 requesting_entity_id,
116 request_id,
117 number_of_missing_pdus,
118 missing_pdu_sequence_numbers,
119 })
120 }
121}
122
123#[cfg(test)]
124mod tests {
125 use super::MinefieldResponseNackPdu;
126 use crate::common::pdu_header::{PduHeader, PduType, ProtocolFamily};
127
128 #[test]
129 fn create_header() {
130 let minefield_response_nack_pdu = MinefieldResponseNackPdu::default();
131 let pdu_header = PduHeader::default(
132 PduType::MinefieldResponseNack,
133 ProtocolFamily::Minefield,
134 448 / 8,
135 );
136
137 assert_eq!(
138 pdu_header.protocol_version,
139 minefield_response_nack_pdu.pdu_header.protocol_version
140 );
141 assert_eq!(
142 pdu_header.exercise_id,
143 minefield_response_nack_pdu.pdu_header.exercise_id
144 );
145 assert_eq!(
146 pdu_header.pdu_type,
147 minefield_response_nack_pdu.pdu_header.pdu_type
148 );
149 assert_eq!(
150 pdu_header.protocol_family,
151 minefield_response_nack_pdu.pdu_header.protocol_family
152 );
153 assert_eq!(
154 pdu_header.length,
155 minefield_response_nack_pdu.pdu_header.length
156 );
157 assert_eq!(
158 pdu_header.status_record,
159 minefield_response_nack_pdu.pdu_header.status_record
160 );
161 }
162}