Coverage Report

Created: 2026-06-30 07:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/sawp-0.13.1/src/error.rs
Line
Count
Source
1
#[cfg(feature = "ffi")]
2
use sawp_ffi::GenerateFFI;
3
4
use std::num::NonZeroUsize;
5
6
// Re-export types used for ErrorKind
7
use nom::error::ErrorKind as NomErrorKind;
8
use nom::Needed as NomNeeded;
9
10
/// Helper that uses this module's error type
11
pub type Result<T> = std::result::Result<T, Error>;
12
13
/// Helper for nom's default error type
14
pub type NomError<I> = nom::error::Error<I>;
15
16
/// Common protocol or parsing error
17
///
18
/// This error type is meant to return the errors that
19
/// are common across parsers and other sub packages.
20
/// Sub packages may choose to implement their own error
21
/// types if they wish to avoid adding extra dependencies
22
/// to the base crate.
23
#[derive(Debug, PartialEq, Eq)]
24
#[cfg_attr(feature = "ffi", derive(GenerateFFI))]
25
#[cfg_attr(feature = "ffi", sawp_ffi(prefix = "sawp"))]
26
pub struct Error {
27
    pub kind: ErrorKind,
28
}
29
30
impl Error {
31
114k
    pub fn new(kind: ErrorKind) -> Self {
32
114k
        Self { kind }
33
114k
    }
34
35
    /// Helper for creating an error with a `ErrorKind::Incomplete` and a needed size.
36
112k
    pub fn incomplete_needed(size: usize) -> Self {
37
112k
        Error::new(ErrorKind::Incomplete(
38
112k
            NonZeroUsize::new(size)
39
112k
                .map(Needed::Size)
40
112k
                .unwrap_or(Needed::Unknown),
41
112k
        ))
42
112k
    }
43
44
    /// Helper for creating an error with a `ErrorKind::Incomplete` and an unknown size.
45
0
    pub fn incomplete() -> Self {
46
0
        Error::new(ErrorKind::Incomplete(Needed::Unknown))
47
0
    }
48
49
    /// Helper for creating a parse error.
50
    #[cfg(feature = "verbose")]
51
    pub fn parse(msg: Option<String>) -> Self {
52
        Error::new(ErrorKind::ParseError(msg))
53
    }
54
55
    /// Helper for creating a parse error.
56
    #[cfg(not(feature = "verbose"))]
57
1.18k
    pub fn parse(_msg: Option<String>) -> Self {
58
1.18k
        Error::new(ErrorKind::ParseError(None))
59
1.18k
    }
60
}
61
62
impl From<ErrorKind> for Error {
63
0
    fn from(kind: ErrorKind) -> Self {
64
0
        Self::new(kind)
65
0
    }
66
}
67
68
/// Number of bytes needed for the next parsing attempt.
69
///
70
/// Used in `ErrorKind::Incomplete` to tell the caller how many bytes to wait
71
/// for before calling the parser with more data.
72
#[derive(Debug, PartialEq, Eq)]
73
pub enum Needed {
74
    Unknown,
75
    Size(NonZeroUsize),
76
}
77
78
/// Kinds of common errors used by the parsers
79
#[derive(Debug, PartialEq, Eq)]
80
#[non_exhaustive]
81
#[cfg_attr(feature = "ffi", derive(GenerateFFI))]
82
#[cfg_attr(feature = "ffi", sawp_ffi(type_only, prefix = "sawp"))]
83
pub enum ErrorKind {
84
    /// Feature is not yet implemented.
85
    Unimplemented,
86
    /// Parser could not advance based on the data provided.
87
    ///
88
    /// Usually indicates the provided input bytes cannot be parsed
89
    /// for the protocol.
90
    //
91
    // Developer note:
92
    //
93
    // This error should only be used as a last resort. Consider
94
    // returning Ok and adding validation error flags to the
95
    // parser's `Message` instead.
96
    InvalidData,
97
    /// Generic parsing error with optional message.
98
    ParseError(Option<String>),
99
    /// Parser did not advance because more data is required to
100
    /// make a decision.
101
    ///
102
    /// The caller should gather more data and try again.
103
    Incomplete(Needed),
104
}
105
106
impl From<NomErrorKind> for ErrorKind {
107
    #[cfg(feature = "verbose")]
108
    fn from(kind: NomErrorKind) -> Self {
109
        Self::ParseError(Some(format!("{:?}", kind)))
110
    }
111
112
    #[cfg(not(feature = "verbose"))]
113
1.05k
    fn from(_kind: NomErrorKind) -> Self {
114
1.05k
        Self::ParseError(None)
115
1.05k
    }
116
}
117
118
impl<I: std::fmt::Debug> From<nom::Err<NomError<I>>> for Error {
119
113k
    fn from(nom_err: nom::Err<NomError<I>>) -> Self {
120
113k
        match nom_err {
121
1.05k
            nom::Err::Error(err) | nom::Err::Failure(err) => Error::new(err.code.into()),
122
112k
            nom::Err::Incomplete(needed) => match needed {
123
0
                NomNeeded::Unknown => Error::incomplete(),
124
112k
                NomNeeded::Size(size) => Error::incomplete_needed(size.into()),
125
            },
126
        }
127
113k
    }
<sawp::error::Error as core::convert::From<nom::internal::Err<nom::error::Error<&[u8]>>>>::from
Line
Count
Source
119
112k
    fn from(nom_err: nom::Err<NomError<I>>) -> Self {
120
112k
        match nom_err {
121
0
            nom::Err::Error(err) | nom::Err::Failure(err) => Error::new(err.code.into()),
122
112k
            nom::Err::Incomplete(needed) => match needed {
123
0
                NomNeeded::Unknown => Error::incomplete(),
124
112k
                NomNeeded::Size(size) => Error::incomplete_needed(size.into()),
125
            },
126
        }
127
112k
    }
Unexecuted instantiation: <sawp::error::Error as core::convert::From<nom::internal::Err<nom::error::Error<_>>>>::from
<sawp::error::Error as core::convert::From<nom::internal::Err<nom::error::Error<&[u8]>>>>::from
Line
Count
Source
119
1.05k
    fn from(nom_err: nom::Err<NomError<I>>) -> Self {
120
1.05k
        match nom_err {
121
1.05k
            nom::Err::Error(err) | nom::Err::Failure(err) => Error::new(err.code.into()),
122
0
            nom::Err::Incomplete(needed) => match needed {
123
0
                NomNeeded::Unknown => Error::incomplete(),
124
0
                NomNeeded::Size(size) => Error::incomplete_needed(size.into()),
125
            },
126
        }
127
1.05k
    }
128
}
129
130
impl std::fmt::Display for Error {
131
0
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> {
132
0
        match &self.kind {
133
0
            ErrorKind::Unimplemented => write!(f, "Unimplemented feature"),
134
0
            ErrorKind::InvalidData => write!(f, "Encountered invalid data"),
135
0
            ErrorKind::ParseError(err) if err.is_some() => {
136
0
                write!(f, "Parsing error: {}", err.clone().unwrap())
137
            }
138
0
            ErrorKind::ParseError(_) => write!(f, "Parsing error"),
139
0
            ErrorKind::Incomplete(Needed::Unknown) => write!(f, "More bytes required to parse"),
140
0
            ErrorKind::Incomplete(Needed::Size(n)) => {
141
0
                write!(f, "{} more bytes required to parse", n)
142
            }
143
        }
144
0
    }
145
}
146
147
impl std::error::Error for Error {}
148
149
impl<I: std::fmt::Debug> From<NomError<I>> for Error {
150
0
    fn from(nom_err: NomError<I>) -> Self {
151
0
        Error::new(nom_err.code.into())
152
0
    }
153
}