Skip to content

Commit

Permalink
Run rustfmt; Use error_chain For Error Types
Browse files Browse the repository at this point in the history
  • Loading branch information
GGist committed Dec 28, 2016
1 parent 202e3a7 commit 4b08461
Show file tree
Hide file tree
Showing 8 changed files with 393 additions and 398 deletions.
3 changes: 3 additions & 0 deletions bip_bencode/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,8 @@ keywords = ["bencode", "bittorrent"]

license = "MIT/Apache-2.0"

[dependencies]
error-chain = "0.7.0"

[features]
unstable = []
59 changes: 29 additions & 30 deletions bip_bencode/src/bencode.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::collections::{BTreeMap};
use std::str::{self};
use std::collections::BTreeMap;
use std::str;

use decode::{self};
use dictionary::{Dictionary};
use decode;
use dictionary::Dictionary;
use error::{BencodeParseResult, BencodeParseError, BencodeParseErrorKind};
use encode::{self};
use encode;

/// Abstract representation of a Bencode object.
pub enum BencodeKind<'b, 'a: 'b> {
Expand All @@ -15,7 +15,7 @@ pub enum BencodeKind<'b, 'a: 'b> {
/// Bencode List.
List(&'b [Bencode<'a>]),
/// Bencode Dictionary.
Dict(&'b Dictionary<'a, Bencode<'a>>)
Dict(&'b Dictionary<'a, Bencode<'a>>),
}

/// Bencode object that holds references to the underlying data.
Expand All @@ -28,72 +28,71 @@ pub enum Bencode<'a> {
/// Bencode List.
List(Vec<Bencode<'a>>),
/// Bencode Dictionary.
Dict(BTreeMap<&'a [u8], Bencode<'a>>)
Dict(BTreeMap<&'a [u8], Bencode<'a>>),
}

impl<'a> Bencode<'a> {
pub fn decode(bytes: &'a [u8]) -> BencodeParseResult<Bencode<'a>> {
// Apply try so any errors return before the eof check
let (bencode, end_pos) = try!(decode::decode(bytes, 0));

if end_pos != bytes.len() {
return Err(BencodeParseError::with_pos(BencodeParseErrorKind::BytesEmpty,
"Some Bytes Were Left Over After Parsing Bencode", Some(end_pos)))
return Err(BencodeParseError::from_kind(BencodeParseErrorKind::BytesEmpty(Some(end_pos))));
}

Ok(bencode)
}

pub fn encode(&self) -> Vec<u8> {
encode::encode(self)
}

pub fn kind<'b>(&'b self) -> BencodeKind<'b, 'a> {
match self {
&Bencode::Int(n) => BencodeKind::Int(n),
&Bencode::Int(n) => BencodeKind::Int(n),
&Bencode::Bytes(ref n) => BencodeKind::Bytes(n),
&Bencode::List(ref n) => BencodeKind::List(n),
&Bencode::Dict(ref n) => BencodeKind::Dict(n)
&Bencode::List(ref n) => BencodeKind::List(n),
&Bencode::Dict(ref n) => BencodeKind::Dict(n),
}
}

pub fn str(&self) -> Option<&'a str> {
let bytes = match self.bytes() {
Some(n) => n,
None => return None
None => return None,
};

match str::from_utf8(bytes) {
Ok(n) => Some(n),
Err(_) => None
Ok(n) => Some(n),
Err(_) => None,
}
}

pub fn int(&self) -> Option<i64> {
match self {
&Bencode::Int(n) => Some(n),
_ => None
_ => None,
}
}

pub fn bytes(&self) -> Option<&'a [u8]> {
match self {
&Bencode::Bytes(ref n) => Some(&n[0..]),
_ => None
_ => None,
}
}

pub fn list(&self) -> Option<&[Bencode<'a>]> {
match self {
match self {
&Bencode::List(ref n) => Some(n),
_ => None
_ => None,
}
}

pub fn dict(&self) -> Option<&Dictionary<'a, Bencode<'a>>> {
match self {
&Bencode::Dict(ref n) => Some(n),
_ => None
_ => None,
}
}
}
}
140 changes: 93 additions & 47 deletions bip_bencode/src/convert.rs
Original file line number Diff line number Diff line change
@@ -1,98 +1,144 @@
use bencode::{Bencode};
use bencode::Bencode;
use error::{BencodeConvertErrorKind, BencodeConvertError};
use dictionary::{Dictionary};
use dictionary::Dictionary;

/// Trait for casting bencode objects and converting conversion errors into application specific errors.
pub trait BencodeConvert {
type Error;

/// Convert the given conversion error into the appropriate error type.
fn handle_error(&self, error: BencodeConvertError) -> Self::Error;

/// Attempt to convert the given bencode value into an integer.
///
/// Error key is used to generate an appropriate error message should the operation return an error.
fn convert_int<'a, E>(&self, bencode: &Bencode<'a>, error_key: E) -> Result<i64, Self::Error>
where E: AsRef<[u8]> {
bencode.int().ok_or(self.handle_error(BencodeConvertError::with_key(BencodeConvertErrorKind::WrongType,
"Bencode Is Not An Integer", error_key.as_ref().to_owned())))
where E: AsRef<[u8]>
{
bencode.int().ok_or(self.handle_error(BencodeConvertError::from_kind(BencodeConvertErrorKind::WrongType(
error_key.as_ref().to_owned(), "Integer".to_owned()
))))
}

/// Attempt to convert the given bencode value into bytes.
///
/// EError key is used to generate an appropriate error message should the operation return an error.
fn convert_bytes<'a, E>(&self, bencode: &Bencode<'a>, error_key: E) -> Result<&'a [u8], Self::Error>
where E: AsRef<[u8]> {
bencode.bytes().ok_or(self.handle_error(BencodeConvertError::with_key(BencodeConvertErrorKind::WrongType,
"Bencode Is Not Bytes", error_key.as_ref().to_owned())))
/// Error key is used to generate an appropriate error message should the operation return an error.
fn convert_bytes<'a, E>(&self,
bencode: &Bencode<'a>,
error_key: E)
-> Result<&'a [u8], Self::Error>
where E: AsRef<[u8]>
{
bencode.bytes().ok_or(self.handle_error(BencodeConvertError::from_kind(BencodeConvertErrorKind::WrongType(
error_key.as_ref().to_owned(), "Bytes".to_owned()
))))
}

/// Attempt to convert the given bencode value into a UTF-8 string.
///
/// Error key is used to generate an appropriate error message should the operation return an error.
fn convert_str<'a, E>(&self, bencode: &Bencode<'a>, error_key: E) -> Result<&'a str, Self::Error>
where E: AsRef<[u8]> {
bencode.str().ok_or(self.handle_error(BencodeConvertError::with_key(BencodeConvertErrorKind::WrongType,
"Bencode Is Not A String", error_key.as_ref().to_owned())))
fn convert_str<'a, E>(&self,
bencode: &Bencode<'a>,
error_key: E)
-> Result<&'a str, Self::Error>
where E: AsRef<[u8]>
{
bencode.str().ok_or(self.handle_error(BencodeConvertError::from_kind(BencodeConvertErrorKind::WrongType(
error_key.as_ref().to_owned(), "UTF-8 Bytes".to_owned()
))))
}

/// Attempty to convert the given bencode value into a list.
///
/// Error key is used to generate an appropriate error message should the operation return an error.
fn convert_list<'a, 'b, E>(&self, bencode: &'b Bencode<'a>, error_key: E)
-> Result<&'b [Bencode<'a>], Self::Error> where E: AsRef<[u8]> {
bencode.list().ok_or(self.handle_error(BencodeConvertError::with_key(BencodeConvertErrorKind::WrongType,
"Bencode Is Not A List", error_key.as_ref().to_owned())))
fn convert_list<'a, 'b, E>(&self,
bencode: &'b Bencode<'a>,
error_key: E)
-> Result<&'b [Bencode<'a>], Self::Error>
where E: AsRef<[u8]>
{
bencode.list().ok_or(self.handle_error(BencodeConvertError::from_kind(BencodeConvertErrorKind::WrongType(
error_key.as_ref().to_owned(), "List".to_owned()
))))
}

/// Attempt to convert the given bencode value into a dictionary.
///
/// Error key is used to generate an appropriate error message should the operation return an error.
fn convert_dict<'a, 'b, E>(&self, bencode: &'b Bencode<'a>, error_key: E)
-> Result<&'b Dictionary<'a, Bencode<'a>>, Self::Error> where E: AsRef<[u8]> {
bencode.dict().ok_or(self.handle_error(BencodeConvertError::with_key(BencodeConvertErrorKind::WrongType,
"Bencode Is Not A Dictionary", error_key.as_ref().to_owned())))
fn convert_dict<'a, 'b, E>(&self,
bencode: &'b Bencode<'a>,
error_key: E)
-> Result<&'b Dictionary<'a, Bencode<'a>>, Self::Error>
where E: AsRef<[u8]>
{
bencode.dict().ok_or(self.handle_error(BencodeConvertError::from_kind(BencodeConvertErrorKind::WrongType(
error_key.as_ref().to_owned(), "Dictionary".to_owned()
))))
}

/// Look up a value in a dictionary of bencoded values using the given key.
fn lookup<'a, 'b, K>(&self, dictionary: &'b Dictionary<'a, Bencode<'a>>, key: K)
-> Result<&'b Bencode<'a>, Self::Error> where K: AsRef<[u8]> {
fn lookup<'a, 'b, K>(&self,
dictionary: &'b Dictionary<'a, Bencode<'a>>,
key: K)
-> Result<&'b Bencode<'a>, Self::Error>
where K: AsRef<[u8]>
{
let key_ref = key.as_ref();

match dictionary.lookup(key_ref) {
Some(n) => Ok(n),
None => Err(self.handle_error(BencodeConvertError::with_key(BencodeConvertErrorKind::MissingKey,
"Dictionary Missing Key", key_ref.to_owned())))
None => Err(self.handle_error(BencodeConvertError::from_kind(BencodeConvertErrorKind::MissingKey(key_ref.to_owned())))),
}
}

/// Combines a lookup operation on the given key with a conversion of the value, if found, to an integer.
fn lookup_and_convert_int<'a, K>(&self, dictionary: &Dictionary<'a, Bencode<'a>>, key: K)
-> Result<i64, Self::Error> where K: AsRef<[u8]> {
fn lookup_and_convert_int<'a, K>(&self,
dictionary: &Dictionary<'a, Bencode<'a>>,
key: K)
-> Result<i64, Self::Error>
where K: AsRef<[u8]>
{
self.convert_int(try!(self.lookup(dictionary, &key)), &key)
}

/// Combines a lookup operation on the given key with a conversion of the value, if found, to a series of bytes.
fn lookup_and_convert_bytes<'a, K>(&self, dictionary: &Dictionary<'a, Bencode<'a>>, key: K)
-> Result<&'a [u8], Self::Error> where K: AsRef<[u8]> {
fn lookup_and_convert_bytes<'a, K>(&self,
dictionary: &Dictionary<'a, Bencode<'a>>,
key: K)
-> Result<&'a [u8], Self::Error>
where K: AsRef<[u8]>
{
self.convert_bytes(try!(self.lookup(dictionary, &key)), &key)
}

/// Combines a lookup operation on the given key with a conversion of the value, if found, to a UTF-8 string.
fn lookup_and_convert_str<'a, K>(&self, dictionary: &Dictionary<'a, Bencode<'a>>, key: K)
-> Result<&'a str, Self::Error> where K: AsRef<[u8]> {
fn lookup_and_convert_str<'a, K>(&self,
dictionary: &Dictionary<'a, Bencode<'a>>,
key: K)
-> Result<&'a str, Self::Error>
where K: AsRef<[u8]>
{
self.convert_str(try!(self.lookup(dictionary, &key)), &key)
}

/// Combines a lookup operation on the given key with a conversion of the value, if found, to a list.
fn lookup_and_convert_list<'a: 'b, 'b, K>(&self, dictionary: &'b Dictionary<'a, Bencode<'a>>, key: K)
-> Result<&'b [Bencode<'a>], Self::Error> where K: AsRef<[u8]> {
fn lookup_and_convert_list<'a: 'b, 'b, K>(&self,
dictionary: &'b Dictionary<'a, Bencode<'a>>,
key: K)
-> Result<&'b [Bencode<'a>], Self::Error>
where K: AsRef<[u8]>
{
self.convert_list(try!(self.lookup(dictionary, &key)), &key)
}

/// Combines a lookup operation on the given key with a conversion of the value, if found, to a dictionary.
fn lookup_and_convert_dict<'a: 'b, 'b, K>(&self, dictionary: &'b Dictionary<'a, Bencode<'a>>, key: K)
-> Result<&'b Dictionary<'a, Bencode<'a>>, Self::Error> where K: AsRef<[u8]> {
fn lookup_and_convert_dict<'a: 'b, 'b, K>
(&self,
dictionary: &'b Dictionary<'a, Bencode<'a>>,
key: K)
-> Result<&'b Dictionary<'a, Bencode<'a>>, Self::Error>
where K: AsRef<[u8]>
{
self.convert_dict(try!(self.lookup(dictionary, &key)), &key)
}
}
Loading

0 comments on commit 4b08461

Please sign in to comment.