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"), } } }