use bencode::{Bencoded};
use self::announce_list::{TierList};
use super::{parse, Torrent};
use util;
pub mod announce_list;
const ANNOUNCE_LIST: &'static str = "announce-list";
const PRIVATE_KEY: &'static str = "private";
pub trait TorrentExt<'a>: Torrent {
fn is_private_tracker(&self) -> bool;
fn announce_list(&'a self) -> Option<TierList<'a>>;
}
impl<'a, 'b: 'a, T, B> TorrentExt<'a> for T
where T: Torrent<BencodeType=B> + 'a, B: Bencoded<Output=B> + 'b {
fn is_private_tracker(&self) -> bool {
let bencode = self.bencode();
let info_dict = parse::slice_info_dict(bencode);
let entry = match info_dict {
Ok(n) => n.lookup(PRIVATE_KEY),
Err(_) => return false
};
match entry.map(|n| n.int()) {
Some(Some(n)) => n == 1,
_ => false
}
}
fn announce_list(&'a self) -> Option<TierList<'a>> {
let bencode = self.bencode();
let root_dict = parse::slice_root_dict(bencode);
let tiers = match root_dict.map( |n| n.lookup(ANNOUNCE_LIST).map( |n| n.list() ) ) {
Ok(Some(Some(n))) => n,
_ => return None
};
let mut tier_list = Vec::with_capacity(tiers.len());
for i in tiers {
let announce_urls = match i.list() {
Some(n) => n,
Non => return None
};
let mut announce_list = Vec::with_capacity(announce_urls.len());
for i in announce_urls {
match i.str() {
Some(n) => announce_list.push(n),
None => return None
};
}
util::fisher_shuffle(&mut announce_list[..]);
tier_list.push(announce_list);
}
Some(TierList::new(tier_list))
}
}