<commit_before>#![allow(dead_code)]

extern crate bencode;

use bencode::{Decodable, Decoder, DecodeError};

enum Info {
    Single,
    Multiple,
}

impl Decodable for Info {
    fn decode(_: &mut Decoder) -> Result<Info, DecodeError> {
        Ok(Info::Single)
    }
}

struct MetaInfo {
    info: Info,
}

impl Decodable for MetaInfo {
    fn decode(d: &mut Decoder) -> Result<MetaInfo, DecodeError> {
        d.read_struct(|d| {
            Ok(MetaInfo{
                info: try!(d.read_field("info"))
            })
        })
    }
}

fn main() {
    println!("hello");
}
<commit_msg>add basic decode example. decoding is done in place so bencode order matters<commit_after>#![allow(dead_code)]

extern crate bencode;

use bencode::{Decodable, Decoder, DecodeError};
use std::fs::File;
use std::io::{self, Read, Write};

struct SingleFile {
    length: i64,
    name: String,
    piece_length: usize,
    //pieces: Vec<u8>,
}
impl Decodable for SingleFile {
    fn decode(d: &mut Decoder) -> Result<SingleFile, DecodeError> {
        d.read_struct(|d| {
            Ok(SingleFile{
                length: try!(d.read_field("length")),
                name: try!(d.read_field("name")),
                piece_length: try!(d.read_field("piece length")),
                //pieces: try!(d.read_field("pieces")),
            })
        })
    }
}

struct MetaInfo {
    pub announce: String,
    pub created_by: String,
    pub comment: String,
    pub encoding: String,
    info: SingleFile,
}

fn read_string_with_default(d: &mut Decoder, field_name: &'static str, default: &'static str) -> String {
    match d.read_field(field_name) {
        Ok(field) => field,
        Err(_) => default.to_string(),
    }
}

impl Decodable for MetaInfo {
    fn decode(d: &mut Decoder) -> Result<MetaInfo, DecodeError> {
        d.read_struct(|d| {
            Ok(MetaInfo{
                announce: try!(d.read_field("announce")),
                comment: try!(d.read_field("comment")),
                created_by: read_string_with_default(d, "created by", ""),
                encoding: try!(d.read_field("encoding")),
                info: try!(d.read_field("info")),
            })
        })
    }
}

fn main() {
    let mut file = File::open("harry.torrent").expect("error opening file");
    let mut buf = Vec::new();
    let _ = file.read_to_end(&mut buf);
    let meta_info = bencode::decode::<MetaInfo>(&buf).unwrap();
    println!("GET {}", meta_info.announce);
    println!("name {}", meta_info.info.name);
    println!("total len {}", meta_info.info.length);
    println!("piece len {}", meta_info.info.piece_length);
    println!("created by {}", meta_info.created_by);
    println!("comment {}", meta_info.comment);
    println!("encoding {}", meta_info.encoding);
}

{'fraction_non_alphanumeric': 0.1565091958168049, 'fraction_numerical': 0.0010818608005769925, 'mean_word_length': 2.713520749665328, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7502839', 'n_tokens_mistral': 910, 'n_tokens_neox': 905, 'n_words': 193}