1#![warn(missing_docs)]
2pub mod compact;
8mod error;
9mod http;
10mod udp;
11
12pub use compact::{
13 encode_compact_peers, encode_compact_peers6, parse_compact_peers, parse_compact_peers6,
14};
15pub use error::{Error, Result};
16pub use http::{HttpAnnounceResponse, HttpScrapeResponse, HttpTracker};
17pub use udp::{UdpAnnounceResponse, UdpScrapeResponse, UdpTracker, UdpTrackerOption};
18
19use std::net::SocketAddr;
20
21use irontide_core::Id20;
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25pub struct ScrapeInfo {
26 pub complete: u32,
28 pub incomplete: u32,
30 pub downloaded: u32,
32}
33
34pub fn announce_url_to_scrape(url: &str) -> Option<String> {
39 let last_pos = url.rfind("announce")?;
40 let mut result = String::with_capacity(url.len());
41 result.push_str(&url[..last_pos]);
42 result.push_str("scrape");
43 result.push_str(&url[last_pos + "announce".len()..]);
44 Some(result)
45}
46
47#[derive(Debug, Clone)]
49pub struct AnnounceRequest {
50 pub info_hash: Id20,
52 pub peer_id: Id20,
54 pub port: u16,
56 pub uploaded: u64,
58 pub downloaded: u64,
60 pub left: u64,
62 pub event: AnnounceEvent,
64 pub num_want: Option<i32>,
66 pub compact: bool,
68 pub i2p_destination: Option<String>,
70}
71
72#[derive(Debug, Clone, Copy, PartialEq, Eq)]
74pub enum AnnounceEvent {
75 None = 0,
77 Completed = 1,
79 Started = 2,
81 Stopped = 3,
83}
84
85#[derive(Debug, Clone)]
87pub struct AnnounceResponse {
88 pub interval: u32,
90 pub seeders: Option<u32>,
92 pub leechers: Option<u32>,
94 pub peers: Vec<SocketAddr>,
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101
102 #[test]
103 fn scrape_info_equality() {
104 let a = ScrapeInfo {
105 complete: 5,
106 incomplete: 3,
107 downloaded: 50,
108 };
109 let b = ScrapeInfo {
110 complete: 5,
111 incomplete: 3,
112 downloaded: 50,
113 };
114 assert_eq!(a, b);
115 }
116
117 #[test]
118 fn announce_to_scrape_url_http() {
119 assert_eq!(
120 announce_url_to_scrape("http://t.co/announce"),
121 Some("http://t.co/scrape".into()),
122 );
123 }
124
125 #[test]
126 fn announce_to_scrape_url_with_path() {
127 assert_eq!(
128 announce_url_to_scrape("http://t.co/path/announce"),
129 Some("http://t.co/path/scrape".into()),
130 );
131 }
132
133 #[test]
134 fn announce_to_scrape_url_no_announce() {
135 assert_eq!(announce_url_to_scrape("http://t.co/track"), None);
136 }
137}