1use crate as neli;
10
11use std::{
12 fmt::{self, Debug},
13 iter::FromIterator,
14 marker::PhantomData,
15 ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Not},
16 slice::{Iter, IterMut},
17};
18
19use crate::{
20 attr::{AttrHandle, AttrHandleMut},
21 consts::{genl::NlAttrType, nl::NlType, rtnl::RtaType},
22 genl::Nlattr,
23 nl::Nlmsghdr,
24 rtnl::Rtattr,
25 FromBytes, FromBytesWithInput, Size, ToBytes, TypeSize,
26};
27
28#[derive(PartialEq, Eq, Size, FromBytesWithInput, ToBytes)]
30pub struct Buffer(#[neli(input)] Vec<u8>);
31
32impl Debug for Buffer {
33 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
34 write!(f, "Buffer")
35 }
36}
37
38impl AsRef<[u8]> for Buffer {
39 fn as_ref(&self) -> &[u8] {
40 self.0.as_slice()
41 }
42}
43
44impl AsMut<[u8]> for Buffer {
45 fn as_mut(&mut self) -> &mut [u8] {
46 self.0.as_mut_slice()
47 }
48}
49
50impl<'a> From<&'a [u8]> for Buffer {
51 fn from(slice: &'a [u8]) -> Self {
52 Buffer(Vec::from(slice))
53 }
54}
55
56impl From<Vec<u8>> for Buffer {
57 fn from(vec: Vec<u8>) -> Self {
58 Buffer(vec)
59 }
60}
61
62impl Buffer {
63 pub fn new() -> Self {
65 Buffer(Vec::new())
66 }
67
68 pub fn extend_from_slice(&mut self, slice: &[u8]) {
70 self.0.extend_from_slice(slice)
71 }
72
73 pub fn len(&self) -> usize {
75 self.0.len()
76 }
77
78 pub fn is_empty(&self) -> bool {
80 self.0.is_empty()
81 }
82}
83
84impl Default for Buffer {
85 fn default() -> Self {
86 Self::new()
87 }
88}
89
90#[derive(Debug, PartialEq, Eq, Size, FromBytesWithInput, ToBytes)]
92#[neli(from_bytes_bound = "T: NlType")]
93#[neli(from_bytes_bound = "P: FromBytesWithInput<Input = usize>")]
94pub struct NlBuffer<T, P>(#[neli(input)] Vec<Nlmsghdr<T, P>>);
95
96impl<T, P> FromIterator<Nlmsghdr<T, P>> for NlBuffer<T, P> {
97 fn from_iter<I>(i: I) -> Self
98 where
99 I: IntoIterator<Item = Nlmsghdr<T, P>>,
100 {
101 NlBuffer(Vec::from_iter(i))
102 }
103}
104
105impl<T, P> AsRef<[Nlmsghdr<T, P>]> for NlBuffer<T, P> {
106 fn as_ref(&self) -> &[Nlmsghdr<T, P>] {
107 self.0.as_slice()
108 }
109}
110
111impl<T, P> NlBuffer<T, P> {
112 pub fn new() -> Self {
114 NlBuffer(Vec::new())
115 }
116
117 pub fn push(&mut self, msg: Nlmsghdr<T, P>) {
119 self.0.push(msg);
120 }
121
122 pub fn pop(&mut self) -> Option<Nlmsghdr<T, P>> {
124 self.0.pop()
125 }
126
127 pub fn iter(&self) -> Iter<'_, Nlmsghdr<T, P>> {
130 self.0.iter()
131 }
132
133 pub fn iter_mut(&mut self) -> IterMut<'_, Nlmsghdr<T, P>> {
136 self.0.iter_mut()
137 }
138
139 pub fn len(&self) -> usize {
141 self.0.len()
142 }
143
144 pub fn is_empty(&self) -> bool {
146 self.0.is_empty()
147 }
148}
149
150impl<T, P> IntoIterator for NlBuffer<T, P> {
151 type Item = Nlmsghdr<T, P>;
152 type IntoIter = <Vec<Nlmsghdr<T, P>> as IntoIterator>::IntoIter;
153
154 fn into_iter(self) -> Self::IntoIter {
155 self.0.into_iter()
156 }
157}
158
159impl<T, P> Default for NlBuffer<T, P> {
160 fn default() -> Self {
161 Self::new()
162 }
163}
164
165#[derive(Debug, PartialEq, Eq, ToBytes, FromBytesWithInput)]
167#[neli(to_bytes_bound = "T: NlAttrType")]
168#[neli(from_bytes_bound = "T: NlAttrType")]
169#[neli(from_bytes_bound = "P: FromBytesWithInput<Input = usize>")]
170pub struct GenlBuffer<T, P>(#[neli(input)] Vec<Nlattr<T, P>>);
171
172impl<T, P> neli::Size for GenlBuffer<T, P>
173where
174 T: Size,
175 P: Size,
176{
177 fn unpadded_size(&self) -> usize {
178 self.0.iter().map(|attr| attr.padded_size()).sum()
179 }
180}
181
182impl<T> GenlBuffer<T, Buffer> {
183 pub fn get_attr_handle(&self) -> AttrHandle<Self, Nlattr<T, Buffer>> {
186 AttrHandle::new_borrowed(self.0.as_ref())
187 }
188
189 pub fn get_attr_handle_mut(&mut self) -> AttrHandleMut<Self, Nlattr<T, Buffer>> {
192 AttrHandleMut::new_borrowed(self.0.as_mut())
193 }
194}
195
196impl<T, P> AsRef<[Nlattr<T, P>]> for GenlBuffer<T, P> {
197 fn as_ref(&self) -> &[Nlattr<T, P>] {
198 self.0.as_slice()
199 }
200}
201
202impl<T, P> AsMut<[Nlattr<T, P>]> for GenlBuffer<T, P> {
203 fn as_mut(&mut self) -> &mut [Nlattr<T, P>] {
204 self.0.as_mut_slice()
205 }
206}
207
208impl<T, P> FromIterator<Nlattr<T, P>> for GenlBuffer<T, P> {
209 fn from_iter<I>(i: I) -> Self
210 where
211 I: IntoIterator<Item = Nlattr<T, P>>,
212 {
213 GenlBuffer(Vec::from_iter(i))
214 }
215}
216
217impl<T, P> IntoIterator for GenlBuffer<T, P> {
218 type Item = Nlattr<T, P>;
219 type IntoIter = <Vec<Nlattr<T, P>> as IntoIterator>::IntoIter;
220
221 fn into_iter(self) -> Self::IntoIter {
222 self.0.into_iter()
223 }
224}
225
226impl<T, P> GenlBuffer<T, P> {
227 pub fn new() -> Self {
229 GenlBuffer(Vec::new())
230 }
231
232 pub fn push(&mut self, attr: Nlattr<T, P>) {
234 self.0.push(attr)
235 }
236
237 pub fn pop(&mut self) -> Option<Nlattr<T, P>> {
239 self.0.pop()
240 }
241
242 pub fn iter(&self) -> Iter<'_, Nlattr<T, P>> {
245 self.0.iter()
246 }
247
248 pub fn iter_mut(&mut self) -> IterMut<'_, Nlattr<T, P>> {
251 self.0.iter_mut()
252 }
253
254 pub fn len(&self) -> usize {
256 self.0.len()
257 }
258
259 pub fn is_empty(&self) -> bool {
261 self.0.is_empty()
262 }
263}
264
265impl<T, P> Default for GenlBuffer<T, P> {
266 fn default() -> Self {
267 Self::new()
268 }
269}
270
271#[derive(Debug, FromBytesWithInput, ToBytes)]
273#[neli(from_bytes_bound = "T: RtaType")]
274#[neli(from_bytes_bound = "P: FromBytesWithInput<Input = usize>")]
275pub struct RtBuffer<T, P>(#[neli(input)] Vec<Rtattr<T, P>>);
276
277impl<T, P> neli::Size for RtBuffer<T, P>
278where
279 T: Size,
280 P: Size,
281{
282 fn unpadded_size(&self) -> usize {
283 self.0.iter().map(|attr| attr.padded_size()).sum()
284 }
285}
286
287impl<T> RtBuffer<T, Buffer> {
288 pub fn get_attr_handle(&self) -> AttrHandle<Self, Rtattr<T, Buffer>> {
291 AttrHandle::new_borrowed(self.0.as_ref())
292 }
293
294 pub fn get_attr_handle_mut(&mut self) -> AttrHandleMut<Self, Rtattr<T, Buffer>> {
297 AttrHandleMut::new_borrowed(self.0.as_mut())
298 }
299}
300
301impl<T, P> FromIterator<Rtattr<T, P>> for RtBuffer<T, P> {
302 fn from_iter<I>(i: I) -> Self
303 where
304 I: IntoIterator<Item = Rtattr<T, P>>,
305 {
306 RtBuffer(Vec::from_iter(i))
307 }
308}
309
310impl<T, P> IntoIterator for RtBuffer<T, P> {
311 type Item = Rtattr<T, P>;
312 type IntoIter = <Vec<Rtattr<T, P>> as IntoIterator>::IntoIter;
313
314 fn into_iter(self) -> Self::IntoIter {
315 self.0.into_iter()
316 }
317}
318
319impl<T, P> AsRef<[Rtattr<T, P>]> for RtBuffer<T, P> {
320 fn as_ref(&self) -> &[Rtattr<T, P>] {
321 self.0.as_slice()
322 }
323}
324
325impl<T, P> AsMut<[Rtattr<T, P>]> for RtBuffer<T, P> {
326 fn as_mut(&mut self) -> &mut [Rtattr<T, P>] {
327 self.0.as_mut_slice()
328 }
329}
330
331impl<T, P> RtBuffer<T, P> {
332 pub fn new() -> Self {
334 RtBuffer(Vec::new())
335 }
336
337 pub fn push(&mut self, attr: Rtattr<T, P>) {
339 self.0.push(attr)
340 }
341
342 pub fn pop(&mut self) -> Option<Rtattr<T, P>> {
344 self.0.pop()
345 }
346
347 pub fn iter(&self) -> Iter<'_, Rtattr<T, P>> {
350 self.0.iter()
351 }
352
353 pub fn iter_mut(&mut self) -> IterMut<'_, Rtattr<T, P>> {
356 self.0.iter_mut()
357 }
358
359 pub fn len(&self) -> usize {
361 self.0.len()
362 }
363
364 pub fn is_empty(&self) -> bool {
366 self.0.is_empty()
367 }
368}
369
370impl<T, P> Default for RtBuffer<T, P> {
371 fn default() -> Self {
372 Self::new()
373 }
374}
375
376#[derive(Debug, PartialEq, Eq, Size, ToBytes, FromBytes)]
380#[neli(from_bytes_bound = "B: FromBytes + TypeSize + Debug")]
381pub struct FlagBuffer<B, T>(B, PhantomData<T>);
382
383impl<'a, B, T> From<&'a [T]> for FlagBuffer<B, T>
384where
385 B: Default + BitOr<B, Output = B> + From<&'a T>,
386{
387 fn from(slice: &'a [T]) -> Self {
388 FlagBuffer(
389 slice
390 .iter()
391 .fold(B::default(), |inner, flag| inner | B::from(flag)),
392 PhantomData,
393 )
394 }
395}
396
397impl<B, T> TypeSize for FlagBuffer<B, T>
398where
399 B: TypeSize,
400{
401 fn type_size() -> usize {
402 B::type_size()
403 }
404}
405
406impl<'a, B, T> FlagBuffer<B, T>
407where
408 B: Default
409 + BitAnd<B, Output = B>
410 + BitAndAssign<B>
411 + BitOr<B, Output = B>
412 + BitOrAssign<B>
413 + Not<Output = B>
414 + From<&'a T>
415 + PartialEq
416 + Copy,
417 T: 'a,
418{
419 pub fn empty() -> Self {
421 FlagBuffer(B::default(), PhantomData)
422 }
423
424 pub fn from_bitmask(bitmask: B) -> Self {
426 FlagBuffer(bitmask, PhantomData)
427 }
428
429 pub fn contains(&self, elem: &'a T) -> bool {
431 (self.0 & elem.into()) == elem.into()
432 }
433
434 pub fn set(&mut self, flag: &'a T) {
436 self.0 |= B::from(flag)
437 }
438
439 pub fn unset(&mut self, flag: &'a T) {
441 self.0 &= !B::from(flag)
442 }
443}
444
445#[cfg(test)]
446mod test {
447 use super::*;
448
449 use crate::consts::{genl::Index, rtnl::Ifa};
450
451 #[test]
452 fn test_genlbuffer_align() {
453 assert_eq!(
454 vec![
455 Nlattr::new(false, false, Index::from(0), 0u8,).unwrap(),
456 Nlattr::new(false, false, Index::from(1), 1u8,).unwrap(),
457 Nlattr::new(false, false, Index::from(2), 2u8,).unwrap(),
458 ]
459 .into_iter()
460 .collect::<GenlBuffer<Index, Buffer>>()
461 .unpadded_size(),
462 24
463 )
464 }
465
466 #[test]
467 fn test_rtbuffer_align() {
468 assert_eq!(
469 vec![
470 Rtattr::new(None, Ifa::Unspec, 0u8,).unwrap(),
471 Rtattr::new(None, Ifa::Address, 1u8,).unwrap(),
472 Rtattr::new(None, Ifa::Local, 2u8,).unwrap(),
473 ]
474 .into_iter()
475 .collect::<RtBuffer<Ifa, Buffer>>()
476 .unpadded_size(),
477 24
478 )
479 }
480}