Skip to main content

proto_packet/io/decode/
decoding_error.rs

1use crate::io::WireType;
2use std::fmt::{Display, Formatter};
3use std::string::FromUtf8Error;
4
5/// A decoding error.
6#[derive(Debug)]
7pub enum DecodingError {
8    /// There was an error reading the stream.
9    Stream(std::io::Error),
10
11    /// The wire type was invalid for the value being decoded.
12    InvalidWireType {
13        semantic: &'static str,
14        wire: WireType,
15    },
16
17    /// The value was out of range.
18    ValueOutOfRange,
19
20    /// The length prefix was out of range.
21    LengthPrefixOutOfRange,
22
23    /// There was an error decoding a packet.
24    InvalidPacket(enc::Error),
25
26    /// A length-prefixed packet's body was shorter than the declared length prefix.
27    ///
28    /// The `declared` field is the byte length the packet's length prefix announced. The `unread`
29    /// field is the number of bytes left in the bounded reader after [Packet::decode_from_read]
30    /// returned. Indicates a buggy [Packet] implementation that under-read its body.
31    PacketUnderRead { declared: usize, unread: usize },
32
33    /// The encoded boolean value was invalid. (must be 0 or 1)
34    InvalidBool(u8),
35
36    /// The encoded string was invalid.
37    InvalidString(FromUtf8Error),
38}
39
40impl DecodingError {
41    //! Construction
42
43    /// Creates a decoding error from the var-int decoding `error`.
44    pub fn from_var_int_error(error: enc::Error) -> Self {
45        match error {
46            enc::Error::Stream(error) => Self::Stream(error),
47            _ => Self::ValueOutOfRange,
48        }
49    }
50
51    /// Creates a decoding error from the var-int length-prefix decoding `error`.
52    pub fn from_length_prefix_error(error: enc::Error) -> Self {
53        match error {
54            enc::Error::Stream(error) => Self::Stream(error),
55            _ => Self::LengthPrefixOutOfRange,
56        }
57    }
58
59    /// Creates a decoding error from the packet decoding `error`.
60    pub fn from_packet_error(error: enc::Error) -> Self {
61        match error {
62            enc::Error::Stream(error) => Self::Stream(error),
63            _ => Self::InvalidPacket(error),
64        }
65    }
66}
67
68impl From<std::io::Error> for DecodingError {
69    fn from(error: std::io::Error) -> Self {
70        Self::Stream(error)
71    }
72}
73
74impl From<DecodingError> for enc::Error {
75    fn from(error: DecodingError) -> Self {
76        match error {
77            DecodingError::Stream(error) => error.into(),
78            _ => enc::Error::InvalidEncodedData {
79                reason: Some(Box::new(error)),
80            },
81        }
82    }
83}
84
85impl Display for DecodingError {
86    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
87        write!(f, "{:?}", self)
88    }
89}
90
91impl std::error::Error for DecodingError {
92    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
93        match self {
94            Self::Stream(error) => Some(error),
95            Self::InvalidPacket(error) => Some(error),
96            Self::InvalidString(error) => Some(error),
97            Self::InvalidWireType { .. }
98            | Self::ValueOutOfRange
99            | Self::LengthPrefixOutOfRange
100            | Self::PacketUnderRead { .. }
101            | Self::InvalidBool(_) => None,
102        }
103    }
104}