Skip to content

Commit 396cde5

Browse files
example: simplify transfer example
1 parent 5d67f47 commit 396cde5

File tree

2 files changed

+96
-51
lines changed

2 files changed

+96
-51
lines changed

examples/transfer.rs

Lines changed: 85 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
use std::{path::PathBuf, str::FromStr};
1+
use std::path::PathBuf;
22

3-
use anyhow::Result;
3+
use anyhow::{bail, Result};
44
use iroh::{protocol::Router, Endpoint};
55
use iroh_blobs::{
66
net_protocol::Blobs,
7-
rpc::client::blobs::{ReadAtLen, WrapOption},
7+
rpc::client::blobs::{self, WrapOption},
8+
store::ExportMode,
89
ticket::BlobTicket,
910
util::SetTagOption,
1011
};
@@ -19,70 +20,103 @@ async fn main() -> Result<()> {
1920

2021
// Now we build a router that accepts blobs connections & routes them
2122
// to the blobs protocol.
22-
let node = Router::builder(endpoint)
23+
let router = Router::builder(endpoint)
2324
.accept(iroh_blobs::ALPN, blobs.clone())
2425
.spawn()
2526
.await?;
2627

27-
let blobs = blobs.client();
28-
29-
let args = std::env::args().collect::<Vec<_>>();
30-
match &args.iter().map(String::as_str).collect::<Vec<_>>()[..] {
31-
[_cmd, "send", path] => {
32-
let abs_path = PathBuf::from_str(path)?.canonicalize()?;
28+
// Grab all passed in arguments, the first one is the binary itself, so we skip it.
29+
let args: Vec<_> = std::env::args().skip(1).collect();
30+
if args.len() < 2 {
31+
print_usage();
32+
bail!("too few arguments");
33+
}
3334

34-
println!("Analyzing file.");
35+
match &*args[0] {
36+
"send" => {
37+
send(&router, blobs.client(), &args).await?;
3538

36-
let blob = blobs
37-
.add_from_path(abs_path, true, SetTagOption::Auto, WrapOption::NoWrap)
38-
.await?
39-
.finish()
40-
.await?;
39+
tokio::signal::ctrl_c().await?;
40+
}
41+
"receive" => {
42+
receive(blobs.client(), &args).await?;
43+
}
44+
cmd => {
45+
print_usage();
46+
bail!("unkown command {}", cmd);
47+
}
48+
}
4149

42-
let node_id = node.endpoint().node_id();
43-
let ticket = BlobTicket::new(node_id.into(), blob.hash, blob.format)?;
50+
// Gracefully shut down the node
51+
println!("Shutting down.");
52+
router.shutdown().await?;
4453

45-
println!("File analyzed. Fetch this file by running:");
46-
println!("cargo run --example transfer -- receive {ticket} {path}");
54+
Ok(())
55+
}
4756

48-
tokio::signal::ctrl_c().await?;
49-
}
50-
[_cmd, "receive", ticket, path] => {
51-
let path_buf = PathBuf::from_str(path)?;
52-
let ticket = BlobTicket::from_str(ticket)?;
57+
async fn send(router: &Router, blobs: &blobs::MemClient, args: &[String]) -> Result<()> {
58+
let path: PathBuf = args[1].parse()?;
59+
let abs_path = path.canonicalize()?;
5360

54-
println!("Starting download.");
61+
println!("Analyzing file.");
5562

56-
blobs
57-
.download(ticket.hash(), ticket.node_addr().clone())
58-
.await?
59-
.finish()
60-
.await?;
63+
// keep the file in place, and link it
64+
let in_place = true;
65+
let blob = blobs
66+
.add_from_path(abs_path, in_place, SetTagOption::Auto, WrapOption::NoWrap)
67+
.await?
68+
.await?;
6169

62-
println!("Finished download.");
63-
println!("Copying to destination.");
70+
let node_id = router.endpoint().node_id();
71+
let ticket = BlobTicket::new(node_id.into(), blob.hash, blob.format)?;
6472

65-
let mut file = tokio::fs::File::create(path_buf).await?;
66-
let mut reader = blobs.read_at(ticket.hash(), 0, ReadAtLen::All).await?;
67-
tokio::io::copy(&mut reader, &mut file).await?;
73+
println!("File analyzed. Fetch this file by running:");
74+
println!(
75+
"cargo run --example transfer -- receive {ticket} {}",
76+
path.display()
77+
);
78+
Ok(())
79+
}
6880

69-
println!("Finished copying.");
70-
}
71-
_ => {
72-
println!("Couldn't parse command line arguments.");
73-
println!("Usage:");
74-
println!(" # to send:");
75-
println!(" cargo run --example transfer -- send [FILE]");
76-
println!(" # this will print a ticket.");
77-
println!();
78-
println!(" # to receive:");
79-
println!(" cargo run --example transfer -- receive [TICKET] [FILE]");
80-
}
81+
async fn receive(blobs: &blobs::MemClient, args: &[String]) -> Result<()> {
82+
if args.len() < 3 {
83+
print_usage();
84+
bail!("too few arguments");
8185
}
86+
let path_buf: PathBuf = args[1].parse()?;
87+
let ticket: BlobTicket = args[2].parse()?;
8288

83-
// Gracefully shut down the node
84-
println!("Shutting down.");
85-
node.shutdown().await?;
89+
println!("Starting download.");
90+
91+
blobs
92+
.download(ticket.hash(), ticket.node_addr().clone())
93+
.await?
94+
.await?;
95+
96+
println!("Finished download.");
97+
println!("Copying to destination.");
98+
99+
blobs
100+
.export(
101+
ticket.hash(),
102+
path_buf,
103+
ticket.format().into(),
104+
ExportMode::Copy,
105+
)
106+
.await?;
107+
108+
println!("Finished copying.");
86109

87110
Ok(())
88111
}
112+
113+
fn print_usage() {
114+
println!("Couldn't parse command line arguments.");
115+
println!("Usage:");
116+
println!(" # to send:");
117+
println!(" cargo run --example transfer -- send [FILE]");
118+
println!(" # this will print a ticket.");
119+
println!();
120+
println!(" # to receive:");
121+
println!(" cargo run --example transfer -- receive [TICKET] [FILE]");
122+
}

src/hash.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use std::{borrow::Borrow, fmt, str::FromStr};
55
use postcard::experimental::max_size::MaxSize;
66
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
77

8+
use crate::store::ExportFormat;
9+
810
/// Hash type used throughout.
911
#[derive(PartialEq, Eq, Copy, Clone, Hash)]
1012
pub struct Hash(blake3::Hash);
@@ -242,6 +244,15 @@ impl BlobFormat {
242244
}
243245
}
244246

247+
impl From<BlobFormat> for ExportFormat {
248+
fn from(value: BlobFormat) -> Self {
249+
match value {
250+
BlobFormat::Raw => ExportFormat::Blob,
251+
BlobFormat::HashSeq => ExportFormat::Collection,
252+
}
253+
}
254+
}
255+
245256
/// A hash and format pair
246257
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, MaxSize, Hash)]
247258
pub struct HashAndFormat {

0 commit comments

Comments
 (0)