use std::path::PathBuf;
use iroh::{protocol::Router, Endpoint};
use iroh_blobs::{store::mem::MemStore, ticket::BlobTicket, BlobsProtocol};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let endpoint = Endpoint::bind().await?;
let store = MemStore::new();
let blobs = BlobsProtocol::new(&store, None);
let args: Vec<String> = std::env::args().skip(1).collect();
let arg_refs: Vec<&str> = args.iter().map(String::as_str).collect();
match arg_refs.as_slice() {
["send", filename] => {
let filename: PathBuf = filename.parse()?;
let abs_path = std::path::absolute(&filename)?;
println!("Hashing file.");
let tag = store.blobs().add_path(abs_path).await?;
let node_id = endpoint.id();
let ticket = BlobTicket::new(node_id.into(), tag.hash, tag.format);
println!("File hashed. Fetch this file by running:");
println!(
"cargo run --example transfer -- receive {ticket} {}",
filename.display()
);
let router = Router::builder(endpoint)
.accept(iroh_blobs::ALPN, blobs)
.spawn();
tokio::signal::ctrl_c().await?;
println!("Shutting down.");
router.shutdown().await?;
}
["receive", ticket, filename] => {
let filename: PathBuf = filename.parse()?;
let abs_path = std::path::absolute(filename)?;
let ticket: BlobTicket = ticket.parse()?;
let downloader = store.downloader(&endpoint);
println!("Starting download.");
downloader
.download(ticket.hash(), Some(ticket.addr().id))
.await?;
println!("Finished download.");
println!("Copying to destination.");
store.blobs().export(ticket.hash(), abs_path).await?;
println!("Finished copying.");
println!("Shutting down.");
endpoint.close().await;
}
_ => {
println!("Couldn't parse command line arguments: {args:?}");
println!("Usage:");
println!(" # to send:");
println!(" cargo run --example transfer -- send [FILE]");
println!(" # this will print a ticket.");
println!();
println!(" # to receive:");
println!(" cargo run --example transfer -- receive [TICKET] [FILE]");
}
}
Ok(())
}