use torrent::metainfo::Metainfo;
use torrent::peer::PeerId;
use torrent::tracker::{AnnounceEvent, AnnounceRequest, Tracker};
use tracing_subscriber::EnvFilter;
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt()
.with_env_filter(EnvFilter::from_default_env())
.init();
let data = include_bytes!("data/ubuntu-26.04-live-server-amd64.iso.torrent");
let meta = Metainfo::try_from(data)?;
let info_hash = meta.info_hash();
println!("Torrent: ubuntu-26.04-live-server-amd64.iso.torrent");
println!("Info hash: {:02x?}", info_hash);
let mut req = AnnounceRequest::new(info_hash, PeerId::random(), 6881);
req.event = AnnounceEvent::Started;
let Some(tracker) = Tracker::from_torrent(meta) else {
eprintln!("no valid trackers found in torrent spec");
return Ok(());
};
println!("\n=== Built-in Trackers (Tracker::from_torrent) ===");
match tracker.announce(&req).await {
Ok(resp) => print_response(&resp),
Err(e) => eprintln!("Tracker failed: {}", e),
}
Ok(())
}
fn print_response(resp: &torrent::tracker::AnnounceResponse) {
println!("Interval: {}s", resp.interval);
if let Some(min) = resp.min_interval {
println!("Min interval: {}s", min);
}
println!("Seeders: {}", resp.complete);
println!("Leechers: {}", resp.incomplete);
println!("Peers found: {}", resp.peers.len());
if let Some(ref warning) = resp.warning_message {
println!("Warning: {}", warning);
}
for (i, peer) in resp.peers.iter().take(10).enumerate() {
println!(" peer {}: {}", i + 1, peer);
}
if resp.peers.len() > 10 {
println!(" ... and {} more", resp.peers.len() - 10);
}
}