netlink_packet_core/
done.rs

1// SPDX-License-Identifier: MIT
2
3use std::mem::size_of;
4
5use crate::{
6    emit_i32, parse_i32, DecodeError, Emitable, ErrorContext, Field, Parseable,
7    Rest,
8};
9
10const CODE: Field = 0..4;
11const EXTENDED_ACK: Rest = 4..;
12pub(crate) const 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    /// Consume the packet, returning the underlying buffer.
26    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
33            .check_buffer_length()
34            .context("invalid DoneBuffer length")?;
35        Ok(packet)
36    }
37
38    fn check_buffer_length(&self) -> Result<(), DecodeError> {
39        let len = self.buffer.as_ref().len();
40        if len < DONE_HEADER_LEN {
41            Err(format!(
42                "invalid DoneBuffer: length is {len} but DoneBuffer are at \
43                 least {DONE_HEADER_LEN} bytes"
44            )
45            .into())
46        } else {
47            Ok(())
48        }
49    }
50
51    /// Return the error code
52    pub fn code(&self) -> i32 {
53        let data = self.buffer.as_ref();
54        parse_i32(&data[CODE]).unwrap()
55    }
56}
57
58impl<'a, T: AsRef<[u8]> + ?Sized> DoneBuffer<&'a T> {
59    /// Return a pointer to the extended ack attributes.
60    pub fn extended_ack(&self) -> &'a [u8] {
61        let data = self.buffer.as_ref();
62        &data[EXTENDED_ACK]
63    }
64}
65
66impl<T: AsRef<[u8]> + AsMut<[u8]> + ?Sized> DoneBuffer<&mut T> {
67    /// Return a mutable pointer to the extended ack attributes.
68    pub fn extended_ack_mut(&mut self) -> &mut [u8] {
69        let data = self.buffer.as_mut();
70        &mut data[EXTENDED_ACK]
71    }
72}
73
74impl<T: AsRef<[u8]> + AsMut<[u8]>> DoneBuffer<T> {
75    /// set the error code field
76    pub fn set_code(&mut self, value: i32) {
77        let data = self.buffer.as_mut();
78        emit_i32(&mut data[CODE], value).unwrap();
79    }
80}
81
82#[derive(Debug, Default, Clone, PartialEq, Eq)]
83#[non_exhaustive]
84pub struct DoneMessage {
85    pub code: i32,
86    pub extended_ack: Vec<u8>,
87}
88
89impl Emitable for DoneMessage {
90    fn buffer_len(&self) -> usize {
91        size_of::<i32>() + self.extended_ack.len()
92    }
93    fn emit(&self, buffer: &mut [u8]) {
94        let mut buffer = DoneBuffer::new(buffer);
95        buffer.set_code(self.code);
96        buffer
97            .extended_ack_mut()
98            .copy_from_slice(&self.extended_ack);
99    }
100}
101
102impl<T: AsRef<[u8]>> Parseable<DoneBuffer<&T>> for DoneMessage {
103    fn parse(buf: &DoneBuffer<&T>) -> Result<DoneMessage, DecodeError> {
104        Ok(DoneMessage {
105            code: buf.code(),
106            extended_ack: buf.extended_ack().to_vec(),
107        })
108    }
109}
110
111#[cfg(test)]
112mod tests {
113    use super::*;
114
115    #[test]
116    fn serialize_and_parse() {
117        let expected = DoneMessage {
118            code: 5,
119            extended_ack: vec![1, 2, 3],
120        };
121
122        let len = expected.buffer_len();
123        assert_eq!(len, size_of::<i32>() + expected.extended_ack.len());
124
125        let mut buf = vec![0; len];
126        expected.emit(&mut buf);
127
128        let done_buf = DoneBuffer::new(&buf);
129        assert_eq!(done_buf.code(), expected.code);
130        assert_eq!(done_buf.extended_ack(), &expected.extended_ack);
131
132        let got = DoneMessage::parse(&done_buf).unwrap();
133        assert_eq!(got, expected);
134    }
135}