1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
//! Structures used to handle errors when serializing or deserializing goes wrong.

use serde::de::Error as DeError;
use serde::de::{Expected, Unexpected};
use serde::ser::Error as SerError;
use std::error::Error as StdError;
use std::fmt;
use std::fmt::Display;
use std::io::Error as IoError;
use std::result::Result as StdResult;

/// Alias for `Result<T, serde_bencode::Error>`.
pub type Result<T> = StdResult<T, Error>;

/// Represents all possible errors which can occur when serializing or deserializing bencode.
#[derive(Debug)]
pub enum Error {
    /// Raised when an IO error occurred.
    IoError(IoError),

    /// Raised when the value being deserialized is of the incorrect type.
    InvalidType(String),

    /// Raised when the value being deserialized is of the right type, but is wrong for some other
    /// reason. For example, this error may occur when deserializing to a String but the input data
    /// is not valid UTF-8.
    InvalidValue(String),

    /// Raised when deserializing a sequence or map, but the input data is the wrong length.
    InvalidLength(String),

    /// Raised when deserializing an enum, but the variant has an unrecognized name.
    UnknownVariant(String),

    /// Raised when deserializing a struct, but there was a field which does not match any of the
    /// expected fields.
    UnknownField(String),

    /// Raised when deserializing a struct, but there was a field which was expected but not
    /// present.
    MissingField(String),

    /// Raised when deserializing a struct, but there is more than one field with the same name.
    DuplicateField(String),

    /// Catchall for any other kind of error.
    Custom(String),

    /// Unexpected end of input stream.
    EndOfStream,
}

impl SerError for Error {
    fn custom<T: Display>(msg: T) -> Self {
        Error::Custom(msg.to_string())
    }
}

impl DeError for Error {
    fn custom<T: Display>(msg: T) -> Self {
        Error::Custom(msg.to_string())
    }

    fn invalid_type(unexpected: Unexpected<'_>, exp: &dyn Expected) -> Self {
        Error::InvalidType(format!("Invalid Type: {unexpected} (expected: `{exp}`)"))
    }

    fn invalid_value(unexpected: Unexpected<'_>, exp: &dyn Expected) -> Self {
        Error::InvalidValue(format!("Invalid Value: {unexpected} (expected: `{exp}`)"))
    }

    fn invalid_length(len: usize, exp: &dyn Expected) -> Self {
        Error::InvalidLength(format!("Invalid Length: {len} (expected: {exp})"))
    }

    fn unknown_variant(field: &str, expected: &'static [&'static str]) -> Self {
        Error::UnknownVariant(format!(
            "Unknown Variant: `{field}` (expected one of: {expected:?})"
        ))
    }

    fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self {
        Error::UnknownField(format!(
            "Unknown Field: `{field}` (expected one of: {expected:?})"
        ))
    }

    fn missing_field(field: &'static str) -> Self {
        Error::MissingField(format!("Missing Field: `{field}`"))
    }

    fn duplicate_field(field: &'static str) -> Self {
        Error::DuplicateField(format!("Duplicate Field: `{field}`"))
    }
}

impl StdError for Error {
    fn source(&self) -> Option<&(dyn StdError + 'static)> {
        match *self {
            Error::IoError(ref error) => Some(error),
            _ => None,
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let message = match *self {
            Error::IoError(ref error) => return error.fmt(f),
            Error::InvalidType(ref s)
            | Error::InvalidValue(ref s)
            | Error::InvalidLength(ref s)
            | Error::UnknownVariant(ref s)
            | Error::UnknownField(ref s)
            | Error::MissingField(ref s)
            | Error::DuplicateField(ref s)
            | Error::Custom(ref s) => s,
            Error::EndOfStream => "End of stream",
        };
        f.write_str(message)
    }
}