1use crate::rtps::messages::{
2 overall_structure::{
3 RtpsMap, Submessage, SubmessageHeader, SubmessageHeaderRead, SubmessageHeaderWrite,
4 },
5 submessage_elements::{LocatorList, SubmessageElement},
6 types::{SubmessageFlag, SubmessageKind},
7};
8
9#[derive(Debug, PartialEq, Eq)]
10pub struct InfoReplySubmessageRead<'a> {
11 data: &'a [u8],
12}
13
14impl SubmessageHeader for InfoReplySubmessageRead<'_> {
15 fn submessage_header(&self) -> SubmessageHeaderRead {
16 SubmessageHeaderRead::new(self.data)
17 }
18}
19
20impl<'a> InfoReplySubmessageRead<'a> {
21 pub fn new(data: &'a [u8]) -> Self {
22 Self { data }
23 }
24
25 pub fn _multicast_flag(&self) -> bool {
26 self.submessage_header().flags()[1]
27 }
28
29 pub fn _unicast_locator_list(&self) -> LocatorList {
30 self.map(&self.data[4..])
31 }
32
33 pub fn _multicast_locator_list(&self) -> LocatorList {
34 if self._multicast_flag() {
35 let num_locators: u32 = self.map(&self.data[4..]);
36 let octets_to_multicat_loctor_list = num_locators as usize * 24 + 8;
37 self.map(&self.data[octets_to_multicat_loctor_list..])
38 } else {
39 LocatorList::new(vec![])
40 }
41 }
42}
43
44#[derive(Debug, PartialEq, Eq)]
45pub struct InfoReplySubmessageWrite<'a> {
46 multicast_flag: SubmessageFlag,
47 submessage_elements: Vec<SubmessageElement<'a>>,
48}
49
50impl<'a> InfoReplySubmessageWrite<'a> {
51 pub fn _new(
52 multicast_flag: SubmessageFlag,
53 unicast_locator_list: LocatorList,
54 multicast_locator_list: LocatorList,
55 ) -> Self {
56 let mut submessage_elements = vec![SubmessageElement::LocatorList(unicast_locator_list)];
57 if multicast_flag {
58 submessage_elements.push(SubmessageElement::LocatorList(multicast_locator_list));
59 }
60 Self {
61 multicast_flag,
62 submessage_elements,
63 }
64 }
65}
66
67impl<'a> Submessage<'a> for InfoReplySubmessageWrite<'a> {
68 type SubmessageList = &'a [SubmessageElement<'a>];
69
70 fn submessage_header(&self, octets_to_next_header: u16) -> SubmessageHeaderWrite {
71 SubmessageHeaderWrite::new(SubmessageKind::INFO_REPLY, &[], octets_to_next_header)
72 }
73
74 fn submessage_elements(&'a self) -> Self::SubmessageList {
75 &self.submessage_elements
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82 use crate::rtps::{
83 messages::overall_structure::{into_bytes_vec, RtpsSubmessageWriteKind},
84 types::Locator,
85 };
86
87 #[test]
88 fn serialize_info_reply() {
89 let locator = Locator::new(11, 12, [1; 16]);
90 let submessage = RtpsSubmessageWriteKind::InfoReply(InfoReplySubmessageWrite::_new(
91 false,
92 LocatorList::new(vec![locator]),
93 LocatorList::new(vec![]),
94 ));
95 #[rustfmt::skip]
96 assert_eq!(into_bytes_vec(submessage), vec![
97 0x0f, 0b_0000_0001, 28, 0, 1, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ]
106 );
107 }
108
109 #[test]
110 fn deserialize_info_reply() {
111 #[rustfmt::skip]
112 let submessage = InfoReplySubmessageRead::new(&[
113 0x0f, 0b_0000_0001, 28, 0, 1, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ]);
122 let locator = Locator::new(11, 12, [1; 16]);
123 let expected_multicast_flag = false;
124 let expected_unicast_locator_list = LocatorList::new(vec![locator]);
125 let expected_multicast_locator_list = LocatorList::new(vec![]);
126
127 assert_eq!(expected_multicast_flag, submessage._multicast_flag());
128 assert_eq!(
129 expected_unicast_locator_list,
130 submessage._unicast_locator_list()
131 );
132 assert_eq!(
133 expected_multicast_locator_list,
134 submessage._multicast_locator_list()
135 );
136 }
137
138 #[test]
139 fn deserialize_info_reply_with_multicast() {
140 #[rustfmt::skip]
141 let submessage = InfoReplySubmessageRead::new(&[
142 0x0f, 0b_0000_0011, 56, 0, 0, 0, 0, 0, 2, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 11, 0, 0, 0, 12, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ]);
158 let locator = Locator::new(11, 12, [1; 16]);
159 let expected_multicast_flag = true;
160 let expected_unicast_locator_list = LocatorList::new(vec![]);
161 let expected_multicast_locator_list = LocatorList::new(vec![locator, locator]);
162
163 assert_eq!(expected_multicast_flag, submessage._multicast_flag());
164 assert_eq!(
165 expected_unicast_locator_list,
166 submessage._unicast_locator_list()
167 );
168 assert_eq!(
169 expected_multicast_locator_list,
170 submessage._multicast_locator_list()
171 );
172 }
173}