use std::{str};
use error::{BencodeResult};
use util::{Dictionary};
mod decode;
mod encode;
const BEN_END: u8 = b'e';
const DICT_START: u8 = b'd';
const LIST_START: u8 = b'l';
const INT_START: u8 = b'i';
const BYTE_LEN_LOW: u8 = b'0';
const BYTE_LEN_HIGH: u8 = b'9';
const BYTE_LEN_END: u8 = b':';
pub use self::decode::{Bencode};
pub enum BencodeKind<'b, 'a: 'b, T> where T: BencodeView<'a> + 'b {
Int(i64),
Bytes(&'a [u8]),
List(&'b [T]),
Dict(&'b Dictionary<'a, T>)
}
pub trait DecodeBencode<T> {
fn decode(T) -> BencodeResult<Self>;
}
pub trait EncodeBencode<T> {
fn encode(self) -> T;
}
impl<'a, T> EncodeBencode<Vec<u8>> for T where T: BencodeView<'a> {
fn encode(self) -> Vec<u8> {
self::encode::encode(self)
}
}
pub trait BencodeView<'a> {
type InnerView: BencodeView<'a> + 'a;
fn str(&self) -> Option<&'a str> {
match self.bytes() {
Some(n) => str::from_utf8(n).ok(),
None => None
}
}
fn kind<'b>(&'b self) -> BencodeKind<'b, 'a, Self::InnerView>;
fn int(&self) -> Option<i64>;
fn bytes(&self) -> Option<&'a [u8]>;
fn list(&self) -> Option<&[Self::InnerView]>;
fn dict(&self) -> Option<&Dictionary<'a, Self::InnerView>>;
}
impl<'a: 'c, 'c, T> BencodeView<'a> for &'c T where T: BencodeView<'a> {
type InnerView = <T as BencodeView<'a>>::InnerView;
fn str(&self) -> Option<&'a str> {
BencodeView::str(*self)
}
fn kind<'b>(&'b self) -> BencodeKind<'b, 'a, Self::InnerView> {
BencodeView::kind(*self)
}
fn int(&self) -> Option<i64> {
BencodeView::int(*self)
}
fn bytes(&self) -> Option<&'a [u8]> {
BencodeView::bytes(*self)
}
fn list(&self) -> Option<&[Self::InnerView]> {
BencodeView::list(*self)
}
fn dict(&self) -> Option<&Dictionary<'a, Self::InnerView>> {
BencodeView::dict(*self)
}
}
impl<'a: 'c, 'c, T> BencodeView<'a> for &'c mut T where T: BencodeView<'a> {
type InnerView = <T as BencodeView<'a>>::InnerView;
fn str(&self) -> Option<&'a str> {
BencodeView::str(*self)
}
fn kind<'b>(&'b self) -> BencodeKind<'b, 'a, Self::InnerView> {
BencodeView::kind(*self)
}
fn int(&self) -> Option<i64> {
BencodeView::int(*self)
}
fn bytes(&self) -> Option<&'a [u8]> {
BencodeView::bytes(*self)
}
fn list(&self) -> Option<&[Self::InnerView]> {
BencodeView::list(*self)
}
fn dict(&self) -> Option<&Dictionary<'a, Self::InnerView>> {
BencodeView::dict(*self)
}
}
mod macros {
#[macro_export]
macro_rules! ben_map {
( $($key:expr => $val:expr),* ) => {
{
use std::convert::{AsRef};
use std::collections::{BTreeMap};
use redox::bencode::{Bencode};
let mut map = BTreeMap::new();
$(
map.insert(AsRef::as_ref($key), $val);
)*
Bencode::Dict(map)
}
}
}
#[macro_export]
macro_rules! ben_list {
( $($ben:expr),* ) => {
{
use redox::bencode::{Bencode};
let mut list = Vec::new();
$(
list.push($ben);
)*
Bencode::List(list)
}
}
}
#[macro_export]
macro_rules! ben_bytes {
( $ben:expr ) => {
{
use std::convert::{AsRef};
use redox::bencode::{Bencode};
Bencode::Bytes(AsRef::as_ref($ben))
}
}
}
#[macro_export]
macro_rules! ben_int {
( $ben:expr ) => {
{
use redox::bencode::{Bencode};
Bencode::Int($ben)
}
}
}
}