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
use serde::{de, ser};
use std::{fmt::Display, str::Utf8Error};

pub type Result<T, E = Error> = std::result::Result<T, E>;

#[derive(Debug, thiserror::Error)]
pub enum Error {
    #[error("{0}")]
    Serde(String),
    #[error("Unexpected end of file")]
    Eof,
    #[error("Trailing bytes")]
    TrailingBytes,
    #[error("Syntax error")]
    Syntax,
    #[error("Leading zeros are forbiden")]
    LeadingZero,
    #[error("Negative zero is not a valid bencode number")]
    NegativeZero,
    #[error("Invalid type")]
    InvalidType,
    #[error("Unexpected Token {found} at index {index}, expected {expected}")]
    UnexpectedToken {
        expected: &'static str,
        found: u8,
        index: usize,
    },
    #[error("Error while parsing utf8 value")]
    Utf8(#[from] Utf8Error),
    #[error("Io Error")]
    Io(#[from] std::io::Error),
    #[error("Unsupported type \"{0}\"")]
    Unsupported(&'static str),
    /// Unexpected end of file while parsing a byte string.
    ///
    /// This usually happens when the specified length is incorrect.
    #[error("Unexpected end of file while parsing a byte string")]
    EofWhileParsingByteString,

    #[error("Expected a dictionary, found a byte string instead")]
    ExpectedDictionaryFoundByteString,
    #[error("Expected a dictionary, found an integer instead")]
    ExpectedDictionaryFoundInteger,
    #[error("Expected a dictionary, found a list instead")]
    ExpectedDictionaryFoundList,

    #[error("Unsorted keys")]
    UnsortedKeys,

    #[error("Integer out of bound")]
    OutOfBound,

    #[error("Map key must be a byte string")]
    MapKeyMustBeByteString,
}

impl Error {
    pub const fn unexpected_token(expected: &'static str, found: u8, index: usize) -> Self {
        Self::UnexpectedToken {
            expected,
            found,
            index,
        }
    }
}

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

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