Skip to content
This repository has been archived by the owner on Oct 23, 2022. It is now read-only.

Commit

Permalink
refactor: showcase restore_bootstrappers in fetch_and_cat
Browse files Browse the repository at this point in the history
  • Loading branch information
Joonas Koivunen committed Oct 7, 2020
1 parent 5071741 commit 2b496ee
Showing 1 changed file with 48 additions and 19 deletions.
67 changes: 48 additions & 19 deletions examples/fetch_and_cat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,27 @@ async fn main() {
// The other connecting or connected peer must be providing the requested CID or this will hang
// forever.

let (path, target) = match parse_options() {
let (bootstrappers, path, target) = match parse_options() {
Ok(Some(tuple)) => tuple,
Ok(None) => {
eprintln!("Usage: fetch_and_cat <IPFS_PATH | CID> [MULTIADDR]");
eprintln!(
"Example will accept connections and print all bytes of the unixfs file to \
stdout."
"Usage: fetch_and_cat [--default-bootstrappers] <IPFS_PATH | CID> [MULTIADDR]"
);
eprintln!();
eprintln!(
"Example will try to find the file by the given IPFS_PATH and print it's contents to stdout."
);
eprintln!();
eprintln!("The example has three modes in the order of precedence:");
eprintln!(
"1. When --default-bootstrappers is given, use default bootstrappers to find the content"
);
eprintln!(
"2. When IPFS_PATH and MULTIADDR are given, connect to MULTIADDR to get the file"
);
eprintln!(
"3. When only IPFS_PATH is given, await to be connected by another ipfs node"
);
eprintln!("If second argument is present, it is expected to be a Multiaddr with \
peer_id. The given Multiaddr will be connected to instead of awaiting an incoming connection.");
exit(0);
}
Err(e) => {
Expand All @@ -54,7 +65,11 @@ async fn main() {
// the libp2p.
tokio::task::spawn(fut);

if let Some(target) = target {
if bootstrappers == BootstrapperOption::RestoreDefault {
// applications wishing to find content on the global IPFS swarm should restore the latest
// bootstrappers which are hopefully updated between releases
ipfs.restore_bootstrappers().await.unwrap();
} else if let Some(target) = target {
ipfs.connect(target).await.unwrap();
} else {
let (_, addresses) = ipfs.identity().await.unwrap();
Expand All @@ -81,20 +96,12 @@ async fn main() {
pin_mut!(stream);

let mut stdout = tokio::io::stdout();
let mut total = 0;

loop {
// This could be made more performant by polling the stream while writing to stdout.
match stream.next().await {
Some(Ok(bytes)) => {
total += bytes.len();
stdout.write_all(&bytes).await.unwrap();

eprintln!(
"Received: {:>12} bytes, Total: {:>12} bytes",
bytes.len(),
total
);
}
Some(Err(e)) => {
eprintln!("Error: {}", e);
Expand All @@ -103,12 +110,34 @@ async fn main() {
None => break,
}
}
}

eprintln!("Total received: {} bytes", total);
#[derive(PartialEq)]
enum BootstrapperOption {
RestoreDefault,
ConnectionsOnly,
}

fn parse_options() -> Result<Option<(IpfsPath, Option<MultiaddrWithPeerId>)>, Error> {
let mut args = env::args().skip(1);
fn parse_options(
) -> Result<Option<(BootstrapperOption, IpfsPath, Option<MultiaddrWithPeerId>)>, Error> {
let mut args = env::args().skip(1).peekable();

// by default use only the manual connections
let mut bootstrappers = BootstrapperOption::ConnectionsOnly;

while let Some(option) = args.peek() {
if !option.starts_with("--") {
break;
}

let option = args.next().expect("already checked when peeking");

if option == "--default-bootstrappers" {
bootstrappers = BootstrapperOption::RestoreDefault;
} else {
return Err(anyhow::format_err!("unknown option: {}", option));
}
}

let path = if let Some(path) = args.next() {
path.parse::<IpfsPath>()
Expand All @@ -129,5 +158,5 @@ fn parse_options() -> Result<Option<(IpfsPath, Option<MultiaddrWithPeerId>)>, Er
None
};

Ok(Some((path, target)))
Ok(Some((bootstrappers, path, target)))
}

0 comments on commit 2b496ee

Please sign in to comment.