1#[macro_export]
4macro_rules! getter {
5 ($buffer: ident, $name:ident, slice, $offset:expr) => {
6 impl<'a, T: AsRef<[u8]> + ?Sized> $buffer<&'a T> {
7 pub fn $name(&self) -> &'a [u8] {
8 &self.buffer.as_ref()[$offset]
9 }
10 }
11 };
12 ($buffer: ident, $name:ident, $ty:tt, $offset:expr) => {
13 impl<'a, T: AsRef<[u8]>> $buffer<T> {
14 getter!($name, $ty, $offset);
15 }
16 };
17 ($name:ident, u8, $offset:expr) => {
18 pub fn $name(&self) -> u8 {
19 self.buffer.as_ref()[$offset]
20 }
21 };
22 ($name:ident, u16, $offset:expr) => {
23 pub fn $name(&self) -> u16 {
24 $crate::parse_u16(&self.buffer.as_ref()[$offset]).unwrap()
25 }
26 };
27 ($name:ident, u32, $offset:expr) => {
28 pub fn $name(&self) -> u32 {
29 $crate::parse_u32(&self.buffer.as_ref()[$offset]).unwrap()
30 }
31 };
32 ($name:ident, u64, $offset:expr) => {
33 pub fn $name(&self) -> u64 {
34 $crate::parse_u64(&self.buffer.as_ref()[$offset]).unwrap()
35 }
36 };
37 ($name:ident, i8, $offset:expr) => {
38 pub fn $name(&self) -> i8 {
39 self.buffer.as_ref()[$offset]
40 }
41 };
42 ($name:ident, i16, $offset:expr) => {
43 pub fn $name(&self) -> i16 {
44 $crate::parse_i16(&self.buffer.as_ref()[$offset]).unwrap()
45 }
46 };
47 ($name:ident, i32, $offset:expr) => {
48 pub fn $name(&self) -> i32 {
49 $crate::parse_i32(&self.buffer.as_ref()[$offset]).unwrap()
50 }
51 };
52 ($name:ident, i64, $offset:expr) => {
53 pub fn $name(&self) -> i64 {
54 $crate::parse_i64(&self.buffer.as_ref()[$offset]).unwrap()
55 }
56 };
57}
58
59#[macro_export]
60macro_rules! setter {
61 ($buffer: ident, $name:ident, slice, $offset:expr) => {
62 impl<'a, T: AsRef<[u8]> + AsMut<[u8]> + ?Sized> $buffer<&'a mut T> {
63 $crate::paste! {
64 pub fn [<$name _mut>](&mut self) -> &mut [u8] {
65 &mut self.buffer.as_mut()[$offset]
66 }
67 }
68 }
69 };
70 ($buffer: ident, $name:ident, $ty:tt, $offset:expr) => {
71 impl<'a, T: AsRef<[u8]> + AsMut<[u8]>> $buffer<T> {
72 setter!($name, $ty, $offset);
73 }
74 };
75 ($name:ident, u8, $offset:expr) => {
76 $crate::paste! {
77 pub fn [<set_ $name>](&mut self, value: u8) {
78 self.buffer.as_mut()[$offset] = value;
79 }
80 }
81 };
82 ($name:ident, u16, $offset:expr) => {
83 $crate::paste! {
84 pub fn [<set_ $name>](&mut self, value: u16) {
85 $crate::emit_u16(&mut self.buffer.as_mut()[$offset], value).unwrap()
86 }
87 }
88 };
89 ($name:ident, u32, $offset:expr) => {
90 $crate::paste! {
91 pub fn [<set_ $name>](&mut self, value: u32) {
92 $crate::emit_u32(&mut self.buffer.as_mut()[$offset], value).unwrap()
93 }
94 }
95 };
96 ($name:ident, u64, $offset:expr) => {
97 $crate::paste! {
98 pub fn [<set_ $name>](&mut self, value: u64) {
99 $crate::emit_u64(&mut self.buffer.as_mut()[$offset], value).unwrap()
100 }
101 }
102 };
103 ($name:ident, i8, $offset:expr) => {
104 $crate::paste! {
105 pub fn [<set_ $name>](&mut self, value: i8) {
106 self.buffer.as_mut()[$offset] = value;
107 }
108 }
109 };
110 ($name:ident, i16, $offset:expr) => {
111 $crate::paste! {
112 pub fn [<set_ $name>](&mut self, value: i16) {
113 $crate::emit_i16(&mut self.buffer.as_mut()[$offset], value).unwrap()
114 }
115 }
116 };
117 ($name:ident, i32, $offset:expr) => {
118 $crate::paste! {
119 pub fn [<set_ $name>](&mut self, value: i32) {
120 $crate::emit_i32(&mut self.buffer.as_mut()[$offset], value).unwrap()
121 }
122 }
123 };
124 ($name:ident, i64, $offset:expr) => {
125 $crate::paste! {
126 pub fn [<set_ $name>](&mut self, value: i64) {
127 $crate::emit_i64(&mut self.buffer.as_mut()[$offset], value).unwrap()
128 }
129 }
130 };
131}
132
133#[macro_export]
134macro_rules! buffer {
135 ($name:ident($buffer_len:expr) { $($field:ident : ($ty:tt, $offset:expr)),* $(,)? }) => {
136 $crate::buffer!($name { $($field: ($ty, $offset),)* });
137 $crate::buffer_check_length!($name($buffer_len));
138 };
139
140 ($name:ident { $($field:ident : ($ty:tt, $offset:expr)),* $(,)? }) => {
141 $crate::buffer_common!($name);
142 fields!($name {
143 $($field: ($ty, $offset),)*
144 });
145 };
146
147 ($name:ident, $buffer_len:expr) => {
148 $crate::buffer_common!($name);
149 $crate::buffer_check_length!($name($buffer_len));
150 };
151
152 ($name:ident) => {
153 $crate::buffer_common!($name);
154 };
155}
156
157#[macro_export]
158macro_rules! fields {
159 ($buffer:ident { $($name:ident : ($ty:tt, $offset:expr)),* $(,)? }) => {
160 $(
161 $crate::getter!($buffer, $name, $ty, $offset);
162 )*
163
164 $(
165 $crate::setter!($buffer, $name, $ty, $offset);
166 )*
167 }
168}
169
170#[macro_export]
171macro_rules! buffer_check_length {
172 ($name:ident($buffer_len:expr)) => {
173 impl<T: AsRef<[u8]>> $name<T> {
174 pub fn new_checked(buffer: T) -> Result<Self, $crate::DecodeError> {
175 let packet = Self::new(buffer);
176 packet.check_buffer_length()?;
177 Ok(packet)
178 }
179
180 fn check_buffer_length(&self) -> Result<(), $crate::DecodeError> {
181 let len = self.buffer.as_ref().len();
182 if len < $buffer_len {
183 Err($crate::DecodeError::invalid_buffer(
184 stringify!($name),
185 len,
186 $buffer_len,
187 ))
188 } else {
189 Ok(())
190 }
191 }
192 }
193 };
194}
195
196#[macro_export]
197macro_rules! buffer_common {
198 ($name:ident) => {
199 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
200 pub struct $name<T> {
201 buffer: T,
202 }
203
204 impl<T: AsRef<[u8]>> $name<T> {
205 pub fn new(buffer: T) -> Self {
206 Self { buffer }
207 }
208
209 pub fn into_inner(self) -> T {
210 self.buffer
211 }
212 }
213
214 impl<'a, T: AsRef<[u8]> + ?Sized> $name<&'a T> {
215 pub fn inner(&self) -> &'a [u8] {
216 &self.buffer.as_ref()[..]
217 }
218 }
219
220 impl<'a, T: AsRef<[u8]> + AsMut<[u8]> + ?Sized> $name<&'a mut T> {
221 pub fn inner_mut(&mut self) -> &mut [u8] {
222 &mut self.buffer.as_mut()[..]
223 }
224 }
225 };
226}