bramble_common/
error.rs

1//! Bramble errors
2
3use serde::{
4    de::{self, Expected, Unexpected},
5    ser,
6};
7use std::{char::CharTryFromError, fmt::Display, io, num::TryFromIntError};
8use thiserror::Error;
9
10/// Bramble errors
11#[derive(Debug, Error)]
12pub enum Error {
13    /// An I/O error has occurred.
14    #[error(transparent)]
15    Io(#[from] io::Error),
16
17    /// An invalid MAC was detected.
18    #[error("invalid MAC")]
19    InvalidMac,
20    /// A key exchange failed.
21    #[error("key exchange failure")]
22    FailedKeyExchange,
23    /// Random number generation failed,
24    #[error("RNG failure")]
25    FailedRng,
26    /// Trailing bytes found in the stream.
27    #[error("unexpected trailing bytes")]
28    TrailingBytes,
29    /// An object with a different type was expected.
30    #[error("encountered wrong data type")]
31    WrongType, // TODO more details
32    /// An invalid object type was found.
33    #[error("invalid data type")]
34    InvalidType,
35    /// An invalid object value was found.
36    #[error("invalid value")]
37    InvalidValue,
38    /// An invalid object length was found.
39    #[error("invalid length")]
40    InvalidLength,
41    /// An invalid object length-of-length was found.
42    #[error("invalid length of length")]
43    InvalidLengthOfLength,
44    /// An older protocol version was found.
45    #[error("older version found")]
46    OlderVersion,
47    /// A beta protocol version was found.
48    #[error("beta version found")]
49    BetaVersion,
50    /// A newer protocol version was found.
51    #[error("newer version found")]
52    NewerVersion,
53    /// An invalid record was received.
54    #[error("invalid record")]
55    InvalidRecord,
56    /// An invalid public key was found.
57    #[error("invalid key found")]
58    InvalidKey,
59    /// An invalid proof of ownership was found.
60    #[error("invalid proof of ownership found")]
61    InvalidProof,
62    /// An empty payload was found.
63    #[error("empty payload")]
64    EmptyPayload,
65    /// An invalid commitment was found.
66    #[error("invalid commitment")]
67    InvalidCommitment,
68    /// An invalid transport was found.
69    #[error("invalid transport")]
70    InvalidTransport,
71    /// An invalid confirmation was received.
72    #[error("invalid confirmation")]
73    InvalidConfirmation,
74    /// Time period in the past.
75    #[error("past time period requested")]
76    TimePeriodIsPast,
77    /// Time has ran out.
78    #[error("time has ran out")]
79    Timeout,
80
81    #[doc(hidden)]
82    #[error("{0:}")]
83    Other(String),
84}
85
86impl Error {
87    /// Helper for creating EOF I/O errors
88    pub fn eof() -> Error {
89        Self::from(io::Error::new(
90            io::ErrorKind::UnexpectedEof,
91            "unexpected end of input",
92        ))
93    }
94
95    /// Helper for matching EOF I/O errors
96    pub fn is_eof(&self) -> bool {
97        matches!(self, Error::Io(e) if e.kind() == io::ErrorKind::UnexpectedEof)
98    }
99}
100
101impl From<TryFromIntError> for Error {
102    fn from(_: TryFromIntError) -> Self {
103        Self::InvalidValue
104    }
105}
106
107impl From<CharTryFromError> for Error {
108    fn from(_: CharTryFromError) -> Self {
109        Self::InvalidValue
110    }
111}
112
113impl From<rand::Error> for Error {
114    fn from(_: rand::Error) -> Self {
115        Self::FailedRng
116    }
117}
118
119impl From<xsalsa20poly1305::aead::Error> for Error {
120    fn from(_: xsalsa20poly1305::aead::Error) -> Self {
121        Self::InvalidMac
122    }
123}
124
125impl ser::Error for Error {
126    fn custom<T: Display>(msg: T) -> Self {
127        Self::Other(msg.to_string())
128    }
129}
130
131impl de::Error for Error {
132    fn custom<T: Display>(msg: T) -> Self {
133        Self::Other(msg.to_string())
134    }
135
136    fn invalid_type(_unexp: Unexpected, _exp: &dyn Expected) -> Self {
137        Self::WrongType
138    }
139
140    fn invalid_value(_unexp: Unexpected, _exp: &dyn Expected) -> Self {
141        Self::InvalidValue
142    }
143
144    fn invalid_length(_len: usize, _exp: &dyn Expected) -> Self {
145        Self::InvalidLength
146    }
147}
148
149/// Result type for Bramble errors.
150pub type Result<T> = std::result::Result<T, Error>;