Skip to main content

dlep_core/
error.rs

1use std::fmt;
2
3use thiserror::Error;
4
5use crate::ids::{DataItemType, MessageType, SignalType};
6
7/// What length(s) a Data Item is permitted to take on the wire, used for
8/// `CodecError::InvalidDataItemLength` reporting. Several DLEP Data Items are
9/// not fixed-width — Connection Points are 5 *or* 7, Status / Peer Type are
10/// "at least 1", Extensions Supported is a multiple of 2 — so a single
11/// `expected: usize` would be misleading.
12#[derive(Clone, Copy, Debug, Eq, PartialEq)]
13pub enum ExpectedLen {
14    /// Length must be exactly this value.
15    Exact(usize),
16    /// Length must be at least this value.
17    AtLeast(usize),
18    /// Length must be one of the listed values.
19    OneOf(&'static [usize]),
20    /// Length must be a non-negative multiple of this value.
21    Multiple(usize),
22}
23
24impl fmt::Display for ExpectedLen {
25    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26        match self {
27            ExpectedLen::Exact(n) => write!(f, "{n}"),
28            ExpectedLen::AtLeast(n) => write!(f, "at least {n}"),
29            ExpectedLen::OneOf(ns) => {
30                write!(f, "one of [")?;
31                for (i, n) in ns.iter().enumerate() {
32                    if i > 0 {
33                        write!(f, ", ")?;
34                    }
35                    write!(f, "{n}")?;
36                }
37                write!(f, "]")
38            }
39            ExpectedLen::Multiple(n) => write!(f, "a multiple of {n}"),
40        }
41    }
42}
43
44#[derive(Debug, Error)]
45pub enum CodecError {
46    #[error("buffer too short: need at least {needed} bytes, have {have}")]
47    Truncated { needed: usize, have: usize },
48
49    #[error("missing DLEP signal prefix")]
50    MissingSignalPrefix,
51
52    #[error("declared length {declared} does not match remaining buffer {remaining}")]
53    LengthMismatch { declared: usize, remaining: usize },
54
55    #[error("unknown signal type {0:?} in strict mode")]
56    UnknownSignalType(SignalType),
57
58    #[error("unknown message type {0:?} in strict mode")]
59    UnknownMessageType(MessageType),
60
61    #[error("unknown data item type {0:?} in strict mode")]
62    UnknownDataItemType(DataItemType),
63
64    #[error("invalid data item length for {kind:?}: expected {expected}, got {got}")]
65    InvalidDataItemLength {
66        kind: DataItemType,
67        expected: ExpectedLen,
68        got: usize,
69    },
70
71    #[error("invalid UTF-8 in text field")]
72    InvalidUtf8(#[from] std::string::FromUtf8Error),
73
74    #[error("i/o error: {0}")]
75    Io(#[from] std::io::Error),
76
77    #[error("value out of range for {field}: {value}")]
78    OutOfRange { field: &'static str, value: u64 },
79}