extern crate serde; extern crate torrust_serde_bencode; #[macro_use] extern crate serde_derive; extern crate serde_bytes; use serde_bytes::ByteBuf; use std::io::{self, Read}; use torrust_serde_bencode::de; #[derive(Debug, Deserialize)] struct Node(String, i64); #[derive(Debug, Deserialize)] struct File { path: Vec, length: i64, #[serde(default)] md5sum: Option, } #[derive(Debug, Deserialize)] struct Info { pub name: String, pub pieces: ByteBuf, #[serde(rename = "piece length")] pub piece_length: i64, #[serde(default)] pub md5sum: Option, #[serde(default)] pub length: Option, #[serde(default)] pub files: Option>, #[serde(default)] pub private: Option, #[serde(default)] pub path: Option>, #[serde(default)] #[serde(rename = "root hash")] pub root_hash: Option, } #[derive(Debug, Deserialize)] struct Torrent { info: Info, #[serde(default)] announce: Option, #[serde(default)] nodes: Option>, #[serde(default)] encoding: Option, #[serde(default)] httpseeds: Option>, #[serde(default)] #[serde(rename = "announce-list")] announce_list: Option>>, #[serde(default)] #[serde(rename = "creation date")] creation_date: Option, #[serde(rename = "comment")] comment: Option, #[serde(default)] #[serde(rename = "created by")] created_by: Option, } fn render_torrent(torrent: &Torrent) { println!("name:\t\t{}", torrent.info.name); println!("announce:\t{:?}", torrent.announce); println!("nodes:\t\t{:?}", torrent.nodes); if let Some(al) = &torrent.announce_list { for a in al { println!("announce list:\t{}", a[0]); } } println!("httpseeds:\t{:?}", torrent.httpseeds); println!("creation date:\t{:?}", torrent.creation_date); println!("comment:\t{:?}", torrent.comment); println!("created by:\t{:?}", torrent.created_by); println!("encoding:\t{:?}", torrent.encoding); println!("piece length:\t{:?}", torrent.info.piece_length); println!("private:\t{:?}", torrent.info.private); println!("root hash:\t{:?}", torrent.info.root_hash); println!("md5sum:\t\t{:?}", torrent.info.md5sum); println!("path:\t\t{:?}", torrent.info.path); if let Some(files) = &torrent.info.files { for f in files { println!("file path:\t{:?}", f.path); println!("file length:\t{}", f.length); println!("file md5sum:\t{:?}", f.md5sum); } } } fn main() { let stdin = io::stdin(); let mut buffer = Vec::new(); let mut handle = stdin.lock(); match handle.read_to_end(&mut buffer) { Ok(_) => match de::from_bytes::(&buffer) { Ok(t) => render_torrent(&t), Err(e) => println!("ERROR: {:?}", e), }, Err(e) => println!("ERROR: {:?}", e), } }