1use crate::{error::*, packet::*};
2use core::fmt;
3
4#[allow(dead_code)]
12#[derive(Debug, PartialEq, Eq, Clone, Copy)]
13pub struct Repr<'a> {
14 pub flags: u8,
16 pub reserved: u32,
18 pub entries: &'a [u8],
20 pub options: &'a [u8],
22}
23
24impl<'a> Repr<'a> {
25 pub fn new(flags: u8, entries: &'a [u8], options: &'a [u8]) -> Self {
38 Repr {
39 flags,
40 reserved: 0,
41 entries,
42 options,
43 }
44 }
45
46 pub fn parse<T>(packet: &'a Packet<T>) -> core::result::Result<Repr<'a>, Error>
56 where
57 T: AsRef<[u8]>,
58 {
59 packet.check_len()?;
60
61 let flags = packet.flags();
62 let reserved = packet.reserved();
63 let entries = packet.entries_array();
64 let options = packet.options_array();
65
66 Ok(Repr {
67 flags,
68 reserved,
69 entries,
70 options,
71 })
72 }
73
74 pub fn emit<T>(&self, packet: &mut Packet<&mut T>)
80 where
81 T: AsRef<[u8]> + AsMut<[u8]> + ?Sized,
82 {
83 packet.set_flags(self.flags);
84 packet.set_reserved(self.reserved);
85 packet.set_entries_length(self.entries.len() as u32);
86
87 let entries_mut = packet.entries_array_mut();
89 entries_mut.copy_from_slice(self.entries);
90
91 packet.set_options_length(self.options.len() as u32);
92
93 let options_mut = packet.options_array_mut();
95 options_mut.copy_from_slice(self.options);
96 }
97
98 pub fn buffer_len(&self) -> usize {
104 use crate::field;
105 field::entries::OPTIONS_ARRAY(self.entries.len(), self.options.len()).end
106 }
107}
108
109impl<'a> fmt::Display for Repr<'a> {
110 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
112 write!(
113 f,
114 "SOME/IP-SD Message: flags=0x{:02X}, entries_len={}, options_len={}",
115 self.flags,
116 self.entries.len(),
117 self.options.len()
118 )
119 }
120}
121
122#[cfg(test)]
123mod tests {
124 use super::*;
125
126 #[test]
127 fn test_repr_new() {
128 let entries = [0u8; 16];
129 let options = [0u8; 8];
130
131 let repr = Repr::new(0x80, &entries, &options);
132
133 assert_eq!(repr.flags, 0x80);
134 assert_eq!(repr.reserved, 0);
135 assert_eq!(repr.entries.len(), 16);
136 assert_eq!(repr.options.len(), 8);
137 }
138
139 #[test]
140 fn test_repr_parse_emit_roundtrip() {
141 let entries_data = [1, 2, 3, 4, 5, 6, 7, 8];
143 let options_data = [9, 10, 11, 12];
144 let original = Repr::new(0xC0, &entries_data, &options_data);
145
146 let mut buffer = [0u8; 12 + 8 + 4];
148 let mut packet = Packet::new_unchecked(&mut buffer[..]);
149 original.emit(&mut packet);
150
151 let parsed = Repr::parse(&packet).unwrap();
153
154 assert_eq!(parsed.flags, original.flags);
155 assert_eq!(parsed.reserved, 0);
156 assert_eq!(parsed.entries, original.entries);
157 assert_eq!(parsed.options, original.options);
158 }
159
160 #[test]
161 fn test_repr_buffer_len() {
162 let entries = [0u8; 32];
163 let options = [0u8; 16];
164
165 let repr = Repr::new(0x00, &entries, &options);
166
167 assert_eq!(repr.buffer_len(), 12 + 32 + 16);
168 }
169
170 #[test]
171 fn test_repr_empty_entries_and_options() {
172 let entries: &[u8] = &[];
173 let options: &[u8] = &[];
174
175 let repr = Repr::new(0x00, entries, options);
176
177 let mut buffer = [0u8; 12];
178 let mut packet = Packet::new_unchecked(&mut buffer[..]);
179 repr.emit(&mut packet);
180
181 assert_eq!(packet.entries_length(), 0);
182 assert_eq!(packet.options_length(), 0);
183 }
184}