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
use std::fmt;

use Error::*;

/// The object structure of a bencode file.
#[derive(Eq, PartialEq, Debug)]
pub enum Bencode {
    /// an integer value. in the format "i{VALUE}e"
    Integer(usize),
    /// a byte string value. in the format "{LENGTH}:{DATA}"
    ByteStr(Vec<u8>),
    /// a list of any Bencode type. in the format "l{BENCODE_OBJECTS}e"
    List(Vec<Bencode>),
    /// a dictionary of bencode values.
    /// as a list of the pair (Bencode::ByteString, Bencode). in the format "d{PAIRS}e"
    Dict(Vec<(Bencode, Bencode)>),
}

impl Bencode {
    pub fn from_bytes(bytes: &[u8]) -> Result {
        crate::parser::parse_child(bytes)
    }
}

/// A Result object comprised of a BencodeWithOffset object, or a BencodeError
pub type Result = std::result::Result<(Bencode, usize), Error>;

impl std::error::Error for Error {}

/// A collection of possible errors that can be encountered while parsing a bencoded file.
#[derive(Debug, Eq, PartialEq)]
pub enum Error {
    // Indicates an expected 'e' was missing. All bencode types except ByteStr expect an 'e' byte
    // after data to indicate the end of the object.
    MissingSentinel,

    // Indicates that the bytes passed to a parse function are not valid ASCII.
    InvalidASCIIBytes,

    // Indicates that bytes passed to a parse function were valid ascii, but could not be parsed to
    // an integer. (in cases like bytestr length, or an integer value.)
    InvalidIntegerString,

    // Indicates that the length specified by a bytestring is longer than the remaining number of
    // bytes passed into the parse function.
    ByteStringLengthOverflow,

    // Indicates that while parsing a dictionary object, a non bytestring key was found.
    BadDictionaryKey,

    // when a character is encountered by the parse_child function, that is not applicable to any
    // of the bencode types.
    NotAValidBencodeByte,

    // Indicates that the first byte of the array passed to a parsing function was not valid.
    // eg: as_int where first byte is not 'i', as_bstr where the first byte is not [0-9], etc.
    BadFirstByte,
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result {
        match self {
            MissingSentinel => write!(f, "Expected to find an 'e' to terminate bencode object."),
            InvalidASCIIBytes => write!(f, "Generic Error Message"),
            InvalidIntegerString => write!(f, "Generic Error Message"),
            ByteStringLengthOverflow => write!(f, "Generic Error Message"),
            BadDictionaryKey => write!(f, "Generic Error Message"),
            NotAValidBencodeByte => write!(f, "Generic Error Message"),
            BadFirstByte => write!(f, "Generic Error Message"),
        }
    }
}