netlink_packet_core/
done.rs
1use std::mem::size_of;
4
5use byteorder::{ByteOrder, NativeEndian};
6use netlink_packet_utils::DecodeError;
7
8use crate::{Emitable, Field, Parseable, Rest};
9
10const CODE: Field = 0..4;
11const EXTENDED_ACK: Rest = 4..;
12const DONE_HEADER_LEN: usize = EXTENDED_ACK.start;
13
14#[derive(Debug, PartialEq, Eq, Clone)]
15#[non_exhaustive]
16pub struct DoneBuffer<T> {
17 buffer: T,
18}
19
20impl<T: AsRef<[u8]>> DoneBuffer<T> {
21 pub fn new(buffer: T) -> DoneBuffer<T> {
22 DoneBuffer { buffer }
23 }
24
25 pub fn into_inner(self) -> T {
27 self.buffer
28 }
29
30 pub fn new_checked(buffer: T) -> Result<Self, DecodeError> {
31 let packet = Self::new(buffer);
32 packet.check_buffer_length()?;
33 Ok(packet)
34 }
35
36 fn check_buffer_length(&self) -> Result<(), DecodeError> {
37 let len = self.buffer.as_ref().len();
38 if len < DONE_HEADER_LEN {
39 Err(format!(
40 "invalid DoneBuffer: length is {len} but DoneBuffer are \
41 at least {DONE_HEADER_LEN} bytes"
42 )
43 .into())
44 } else {
45 Ok(())
46 }
47 }
48
49 pub fn code(&self) -> i32 {
51 let data = self.buffer.as_ref();
52 NativeEndian::read_i32(&data[CODE])
53 }
54}
55
56impl<'a, T: AsRef<[u8]> + ?Sized> DoneBuffer<&'a T> {
57 pub fn extended_ack(&self) -> &'a [u8] {
59 let data = self.buffer.as_ref();
60 &data[EXTENDED_ACK]
61 }
62}
63
64impl<'a, T: AsRef<[u8]> + AsMut<[u8]> + ?Sized> DoneBuffer<&'a mut T> {
65 pub fn extended_ack_mut(&mut self) -> &mut [u8] {
67 let data = self.buffer.as_mut();
68 &mut data[EXTENDED_ACK]
69 }
70}
71
72impl<T: AsRef<[u8]> + AsMut<[u8]>> DoneBuffer<T> {
73 pub fn set_code(&mut self, value: i32) {
75 let data = self.buffer.as_mut();
76 NativeEndian::write_i32(&mut data[CODE], value)
77 }
78}
79
80#[derive(Debug, Default, Clone, PartialEq, Eq)]
81#[non_exhaustive]
82pub struct DoneMessage {
83 pub code: i32,
84 pub extended_ack: Vec<u8>,
85}
86
87impl Emitable for DoneMessage {
88 fn buffer_len(&self) -> usize {
89 size_of::<i32>() + self.extended_ack.len()
90 }
91 fn emit(&self, buffer: &mut [u8]) {
92 let mut buffer = DoneBuffer::new(buffer);
93 buffer.set_code(self.code);
94 buffer.extended_ack_mut().copy_from_slice(&self.extended_ack);
95 }
96}
97
98impl<'buffer, T: AsRef<[u8]> + 'buffer> Parseable<DoneBuffer<&'buffer T>> for DoneMessage {
99 type Error = DecodeError;
100 fn parse(buf: &DoneBuffer<&'buffer T>) -> Result<DoneMessage, DecodeError> {
101 Ok(DoneMessage { code: buf.code(), extended_ack: buf.extended_ack().to_vec() })
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108
109 #[test]
110 fn serialize_and_parse() {
111 let expected = DoneMessage { code: 5, extended_ack: vec![1, 2, 3] };
112
113 let len = expected.buffer_len();
114 assert_eq!(len, size_of::<i32>() + expected.extended_ack.len());
115
116 let mut buf = vec![0; len];
117 expected.emit(&mut buf);
118
119 let done_buf = DoneBuffer::new(&buf);
120 assert_eq!(done_buf.code(), expected.code);
121 assert_eq!(done_buf.extended_ack(), &expected.extended_ack);
122
123 let got = DoneMessage::parse(&done_buf).unwrap();
124 assert_eq!(got, expected);
125 }
126}