Skip to content

Commit 63da36a

Browse files
committed
Extend ErrorContext to accept std::fmt::Display
Signed-off-by: Gris Ge <fge@redhat.com>
1 parent cc6bf08 commit 63da36a

File tree

1 file changed

+31
-16
lines changed

1 file changed

+31
-16
lines changed

src/error.rs

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,34 @@
22

33
use std::{fmt, io, mem::size_of, num::NonZeroI32};
44

5-
use byteorder::{ByteOrder, NativeEndian};
6-
7-
use crate::{Emitable, Field, Parseable, Rest};
5+
use crate::{emit_i32, parse_i32, Emitable, Field, Parseable, Rest};
86

97
const CODE: Field = 0..4;
108
const PAYLOAD: Rest = 4..;
119
const ERROR_HEADER_LEN: usize = PAYLOAD.start;
1210

13-
pub trait ErrorContext {
14-
fn context(self, msg: &str) -> Self;
11+
pub trait ErrorContext<T: std::fmt::Display> {
12+
fn context(self, msg: T) -> Self;
1513
}
1614

1715
#[derive(Debug)]
1816
pub struct DecodeError {
1917
msg: String,
2018
}
2119

22-
impl ErrorContext for DecodeError {
23-
fn context(self, msg: &str) -> Self {
20+
impl<T: std::fmt::Display> ErrorContext<T> for DecodeError {
21+
fn context(self, msg: T) -> Self {
2422
Self {
2523
msg: format!("{} caused by {}", msg, self.msg),
2624
}
2725
}
2826
}
2927

30-
impl<T> ErrorContext for Result<T, DecodeError>
28+
impl<T, M> ErrorContext<M> for Result<T, DecodeError>
3129
where
32-
T: Clone,
30+
M: std::fmt::Display,
3331
{
34-
fn context(self, msg: &str) -> Result<T, DecodeError> {
32+
fn context(self, msg: M) -> Result<T, DecodeError> {
3533
match self {
3634
Ok(t) => Ok(t),
3735
Err(e) => Err(e.context(msg)),
@@ -70,6 +68,19 @@ impl std::fmt::Display for DecodeError {
7068
impl std::error::Error for DecodeError {}
7169

7270
impl DecodeError {
71+
pub fn invalid_buffer(
72+
name: &str,
73+
received: usize,
74+
minimum_length: usize,
75+
) -> Self {
76+
Self {
77+
msg: format!(
78+
"Invalid buffer {name}. \
79+
Expected at least {minimum_length} bytes, \
80+
received {received} bytes"
81+
),
82+
}
83+
}
7384
pub fn invalid_mac_address(received: usize) -> Self {
7485
Self{
7586
msg: format!("Invalid MAC address. Expected 6 bytes, received {received} bytes"),
@@ -105,6 +116,12 @@ impl DecodeError {
105116
msg: format!("NLA has invalid length: {nla_len} (should be at least {buffer_len} bytes)"),
106117
}
107118
}
119+
120+
pub fn buffer_too_small(buffer_len: usize, value_len: usize) -> Self {
121+
Self {
122+
msg: format!("Buffer too small: {buffer_len} (should be at least {value_len} bytes"),
123+
}
124+
}
108125
}
109126

110127
#[derive(Debug, PartialEq, Eq, Clone)]
@@ -152,7 +169,7 @@ impl<T: AsRef<[u8]>> ErrorBuffer<T> {
152169
/// message is a NACK).
153170
pub fn code(&self) -> Option<NonZeroI32> {
154171
let data = self.buffer.as_ref();
155-
NonZeroI32::new(NativeEndian::read_i32(&data[CODE]))
172+
NonZeroI32::new(parse_i32(&data[CODE]).unwrap())
156173
}
157174
}
158175

@@ -176,7 +193,7 @@ impl<T: AsRef<[u8]> + AsMut<[u8]>> ErrorBuffer<T> {
176193
/// set the error code field
177194
pub fn set_code(&mut self, value: i32) {
178195
let data = self.buffer.as_mut();
179-
NativeEndian::write_i32(&mut data[CODE], value)
196+
emit_i32(&mut data[CODE], value).unwrap();
180197
}
181198
}
182199

@@ -215,9 +232,7 @@ impl Emitable for ErrorMessage {
215232
}
216233

217234
impl<T: AsRef<[u8]>> Parseable<ErrorBuffer<&T>> for ErrorMessage {
218-
type Error = DecodeError;
219-
220-
fn parse(buf: &ErrorBuffer<&T>) -> Result<ErrorMessage, Self::Error> {
235+
fn parse(buf: &ErrorBuffer<&T>) -> Result<ErrorMessage, DecodeError> {
221236
// FIXME: The payload of an error is basically a truncated packet, which
222237
// requires custom logic to parse correctly. For now we just
223238
// return it as a Vec<u8> let header: NetlinkHeader = {
@@ -300,7 +315,7 @@ mod tests {
300315
// SAFETY: value is non-zero.
301316
const ERROR_CODE: NonZeroI32 = NonZeroI32::new(-1234).unwrap();
302317
let mut bytes = vec![0, 0, 0, 0];
303-
NativeEndian::write_i32(&mut bytes, ERROR_CODE.get());
318+
emit_i32(&mut bytes, ERROR_CODE.get()).unwrap();
304319
let msg = ErrorBuffer::new_checked(&bytes)
305320
.and_then(|buf| ErrorMessage::parse(&buf))
306321
.expect("failed to parse NLMSG_ERROR");

0 commit comments

Comments
 (0)