use access::bencode::BRefAccessExt;
use access::bencode::BRefAccess;
use error::{BencodeConvertErrorKind, BencodeConvertError};
use access::dict::BDictAccess;
use access::list::BListAccess;
pub trait BConvertExt: BConvert {
fn convert_bytes_ext<'a, B, E>(&self, bencode: B, error_key: E) -> Result<&'a [u8], Self::Error>
where B: BRefAccessExt<'a>, E: AsRef<[u8]>
{
bencode.bytes_ext().ok_or(self.handle_error(BencodeConvertError::from_kind(BencodeConvertErrorKind::WrongType{
key: error_key.as_ref().to_owned(), expected_type: "Bytes".to_owned()
})))
}
fn convert_str_ext<'a, B, E>(&self, bencode: &B, error_key: E) -> Result<&'a str, Self::Error>
where B: BRefAccessExt<'a>, E: AsRef<[u8]>
{
bencode.str_ext().ok_or(self.handle_error(BencodeConvertError::from_kind(BencodeConvertErrorKind::WrongType{
key: error_key.as_ref().to_owned(), expected_type: "UTF-8 Bytes".to_owned()
})))
}
fn lookup_and_convert_bytes_ext<'a, B, K1, K2>(&self, dictionary: &BDictAccess<K1, B>, key: K2) -> Result<&'a [u8], Self::Error>
where B: BRefAccessExt<'a>, K2: AsRef<[u8]>
{
self.convert_bytes_ext(try!(self.lookup(dictionary, &key)), &key)
}
fn lookup_and_convert_str_ext<'a, B, K1, K2>(&self, dictionary: &BDictAccess<K1, B>, key: K2) -> Result<&'a str, Self::Error>
where B: BRefAccessExt<'a>, K2: AsRef<[u8]>
{
self.convert_str_ext(try!(self.lookup(dictionary, &key)), &key)
}
}
pub trait BConvert {
type Error;
fn handle_error(&self, error: BencodeConvertError) -> Self::Error;
fn convert_int<B, E>(&self, bencode: B, error_key: E) -> Result<i64, Self::Error>
where B: BRefAccess, E: AsRef<[u8]>
{
bencode.int().ok_or(self.handle_error(BencodeConvertError::from_kind(BencodeConvertErrorKind::WrongType{
key: error_key.as_ref().to_owned(), expected_type: "Integer".to_owned()
})))
}
fn convert_bytes<'a, B, E>(&self, bencode: &'a B, error_key: E) -> Result<&'a [u8], Self::Error>
where B: BRefAccess, E: AsRef<[u8]>
{
bencode.bytes().ok_or(self.handle_error(BencodeConvertError::from_kind(BencodeConvertErrorKind::WrongType{
key: error_key.as_ref().to_owned(), expected_type: "Bytes".to_owned()
})))
}
fn convert_str<'a, B, E>(&self, bencode: &'a B, error_key: E) -> Result<&'a str, Self::Error>
where B: BRefAccess, E: AsRef<[u8]>
{
bencode.str().ok_or(self.handle_error(BencodeConvertError::from_kind(BencodeConvertErrorKind::WrongType{
key: error_key.as_ref().to_owned(), expected_type: "UTF-8 Bytes".to_owned()
})))
}
fn convert_list<'a, B, E>(&self, bencode: &'a B, error_key: E) -> Result<&'a BListAccess<B::BType>, Self::Error>
where B: BRefAccess, E: AsRef<[u8]>
{
bencode.list().ok_or(self.handle_error(BencodeConvertError::from_kind(BencodeConvertErrorKind::WrongType{
key: error_key.as_ref().to_owned(), expected_type: "List".to_owned()
})))
}
fn convert_dict<'a, B, E>(&self, bencode: &'a B, error_key: E) -> Result<&'a BDictAccess<B::BKey, B::BType>, Self::Error>
where B: BRefAccess, E: AsRef<[u8]>
{
bencode.dict().ok_or(self.handle_error(BencodeConvertError::from_kind(BencodeConvertErrorKind::WrongType{
key: error_key.as_ref().to_owned(), expected_type: "Dictionary".to_owned()
})))
}
fn lookup<'a, B, K1, K2>(&self, dictionary: &'a BDictAccess<K1, B>, key: K2) -> Result<&'a B, Self::Error>
where B: BRefAccess, K2: AsRef<[u8]>
{
let key_ref = key.as_ref();
match dictionary.lookup(key_ref) {
Some(n) => Ok(n),
None => Err(self.handle_error(BencodeConvertError::from_kind(BencodeConvertErrorKind::MissingKey{ key: key_ref.to_owned() }))),
}
}
fn lookup_and_convert_int<B, K1, K2>(&self, dictionary: &BDictAccess<K1, B>, key: K2) -> Result<i64, Self::Error>
where B: BRefAccess, K2: AsRef<[u8]>
{
self.convert_int(try!(self.lookup(dictionary, &key)), &key)
}
fn lookup_and_convert_bytes<'a, B, K1, K2>(&self, dictionary: &'a BDictAccess<K1, B>, key: K2) -> Result<&'a [u8], Self::Error>
where B: BRefAccess, K2: AsRef<[u8]>
{
self.convert_bytes(try!(self.lookup(dictionary, &key)), &key)
}
fn lookup_and_convert_str<'a, B, K1, K2>(&self, dictionary: &'a BDictAccess<K1, B>, key: K2) -> Result<&'a str, Self::Error>
where B: BRefAccess, K2: AsRef<[u8]>
{
self.convert_str(try!(self.lookup(dictionary, &key)), &key)
}
fn lookup_and_convert_list<'a, B, K1, K2>(&self, dictionary: &'a BDictAccess<K1, B>, key: K2) -> Result<&'a BListAccess<B::BType>, Self::Error>
where B: BRefAccess, K2: AsRef<[u8]>
{
self.convert_list(try!(self.lookup(dictionary, &key)), &key)
}
fn lookup_and_convert_dict<'a, B, K1, K2>(&self, dictionary: &'a BDictAccess<K1, B>, key: K2) -> Result<&'a BDictAccess<B::BKey, B::BType>, Self::Error>
where B: BRefAccess, K2: AsRef<[u8]>
{
self.convert_dict(try!(self.lookup(dictionary, &key)), &key)
}
}