forked from toby/serde-bencode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
parse_torrent.rs
104 lines (97 loc) · 2.89 KB
/
parse_torrent.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#[macro_use]
extern crate serde_derive;
use serde_bencode::de;
use serde_bytes::ByteBuf;
use std::io::{self, Read};
#[derive(Debug, Deserialize)]
struct Node(String, i64);
#[derive(Debug, Deserialize)]
struct File {
path: Vec<String>,
length: i64,
#[serde(default)]
md5sum: Option<String>,
}
#[allow(dead_code)]
#[derive(Debug, Deserialize)]
struct Info {
pub name: String,
pub pieces: ByteBuf,
#[serde(rename = "piece length")]
pub piece_length: i64,
#[serde(default)]
pub md5sum: Option<String>,
#[serde(default)]
pub length: Option<i64>,
#[serde(default)]
pub files: Option<Vec<File>>,
#[serde(default)]
pub private: Option<u8>,
#[serde(default)]
pub path: Option<Vec<String>>,
#[serde(default)]
#[serde(rename = "root hash")]
pub root_hash: Option<String>,
}
#[derive(Debug, Deserialize)]
struct Torrent {
info: Info,
#[serde(default)]
announce: Option<String>,
#[serde(default)]
nodes: Option<Vec<Node>>,
#[serde(default)]
encoding: Option<String>,
#[serde(default)]
httpseeds: Option<Vec<String>>,
#[serde(default)]
#[serde(rename = "announce-list")]
announce_list: Option<Vec<Vec<String>>>,
#[serde(default)]
#[serde(rename = "creation date")]
creation_date: Option<i64>,
#[serde(rename = "comment")]
comment: Option<String>,
#[serde(default)]
#[serde(rename = "created by")]
created_by: Option<String>,
}
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::<Torrent>(&buffer) {
Ok(t) => render_torrent(&t),
Err(e) => println!("ERROR: {e:?}"),
},
Err(e) => println!("ERROR: {e:?}"),
}
}