From 0cd34b196863325132e54bc8f36b196659baeb17 Mon Sep 17 00:00:00 2001 From: Ferris Tseng Date: Wed, 13 Feb 2019 21:51:57 -0500 Subject: formatting; docs update; version increment; small refactors --- README.md | 87 +++++++++- ipfs-api/Cargo.toml | 4 +- ipfs-api/examples/bootstrap_default.rs | 22 +-- ipfs-api/examples/get_version.rs | 2 +- ipfs-api/examples/mfs.rs | 70 ++++---- ipfs-api/examples/ping_peer.rs | 2 +- ipfs-api/src/client.rs | 20 +-- ipfs-api/src/lib.rs | 287 ++++++++++++++++++--------------- ipfs-cli/Cargo.toml | 4 +- 9 files changed, 300 insertions(+), 198 deletions(-) diff --git a/README.md b/README.md index 92341ac..e451f2c 100644 --- a/README.md +++ b/README.md @@ -10,12 +10,21 @@ Rust library for connecting to the IPFS HTTP API using tokio. ```toml [dependencies] -ipfs-api = "0.5.0-alpha2" +ipfs-api = "0.5.1" +``` + +You can use `actix-web` as a backend instead of `hyper`. + +```toml +[dependencies] +ipfs-api = { version = "0.5.1", features = ["actix"], default-features = false } ``` ### Examples -Write a file to IPFS: +#### Writing a file to IPFS + +##### With Hyper ```rust # @@ -36,7 +45,35 @@ let req = client hyper::rt::run(req); ``` -Read a file from IPFS: +##### With Actix + +```rust +# +use futures::future::Future; +use ipfs_api::IpfsClient; +use std::io::Cursor; + +let client = IpfsClient::default(); +let data = Cursor::new("Hello World!"); + +let req = client + .add(data) + .map(|res| { + println!("{}", res.hash); + }) + .map_err(|e| eprintln!("{}", e)); + +actix_web::actix::run(|| { + req.then(|_| { + actix_web::actix::System::current().stop(); + Ok(()) + }) +}); +``` + +#### Reading a file from IPFS + +##### With Hyper ```rust # @@ -60,15 +97,59 @@ let req = client hyper::rt::run(req); ``` +##### With Actix + +```rust +# +use futures::{Future, Stream}; +use ipfs_api::IpfsClient; +use std::io::{self, Write}; + +let client = IpfsClient::default(); + +let req = client + .get("/test/file.json") + .concat2() + .map(|res| { + let out = io::stdout(); + let mut out = out.lock(); + + out.write_all(&res).unwrap(); + }) + .map_err(|e| eprintln!("{}", e)); + +actix_web::actix::run(|| { + req.then(|_| { + actix_web::actix::System::current().stop(); + Ok(()) + }) +}); +``` + +#### Additional Examples + There are also a bunch of examples included in the project, which I used for testing +For a list of examples, run: + +```sh +$ cargo run --example +``` + You can run any of the examples with cargo: ```sh $ cargo run -p ipfs-api --example add_file ``` +To run an example with the `actix-web` backend, use: + +```sh +$ cargo run -p ipfs-api --features actix --no-default-features --example add_file +``` + + ## License Licensed under either of diff --git a/ipfs-api/Cargo.toml b/ipfs-api/Cargo.toml index 39cad56..c75ad20 100644 --- a/ipfs-api/Cargo.toml +++ b/ipfs-api/Cargo.toml @@ -6,7 +6,7 @@ documentation = "https://docs.rs/ipfs-api" repository = "https://github.com/ferristseng/rust-ipfs-api" keywords = ["ipfs"] categories = ["filesystem", "web-programming"] -version = "0.5.0-alpha2" +version = "0.5.1" readme = "../README.md" license = "MIT OR Apache-2.0" @@ -38,5 +38,7 @@ dirs = "1.0" multiaddr = "0.3.1" [dev-dependencies] +actix-multipart-rfc7578 = "0.1" +actix-web = "0.7" tokio-timer = "0.2" tar = "0.4" diff --git a/ipfs-api/examples/bootstrap_default.rs b/ipfs-api/examples/bootstrap_default.rs index bc36952..e03c5d6 100644 --- a/ipfs-api/examples/bootstrap_default.rs +++ b/ipfs-api/examples/bootstrap_default.rs @@ -46,19 +46,19 @@ fn main() { }); let fut = bootstrap - .and_then(|_| { - println!(); - println!("dropping all bootstrap peers..."); + .and_then(|_| { + println!(); + println!("dropping all bootstrap peers..."); - drop - }) - .and_then(|_| { - println!(); - println!("adding default peers..."); + drop + }) + .and_then(|_| { + println!(); + println!("adding default peers..."); - add - }) - .map_err(|e| eprintln!("{}", e)); + add + }) + .map_err(|e| eprintln!("{}", e)); #[cfg(feature = "hyper")] hyper::rt::run(fut); diff --git a/ipfs-api/examples/get_version.rs b/ipfs-api/examples/get_version.rs index 6fb9c7e..d8b0f65 100644 --- a/ipfs-api/examples/get_version.rs +++ b/ipfs-api/examples/get_version.rs @@ -27,7 +27,7 @@ fn main() { .map(|version| println!("version: {:?}", version.version)); let fut = req.map_err(|e| eprintln!("{}", e)); - + #[cfg(feature = "hyper")] hyper::rt::run(fut); #[cfg(feature = "actix")] diff --git a/ipfs-api/examples/mfs.rs b/ipfs-api/examples/mfs.rs index 97d1824..06a849e 100644 --- a/ipfs-api/examples/mfs.rs +++ b/ipfs-api/examples/mfs.rs @@ -49,42 +49,40 @@ fn main() { let file_rm = client.files_rm("/test", true); - let fut = - mkdir - .and_then(|_| { - println!("making dirs /test/does/not/exist/yet..."); - println!(); - - mkdir_recursive - }) - .and_then(|_| { - println!("getting status of /test/does..."); - println!(); - - file_stat - }) - .and_then(|stat| { - print_stat(stat); - - println!("writing source file to /test/mfs.rs"); - println!(); - - file_write - }) - .and_then(|_| file_write_stat) - .and_then(|stat| { - print_stat(stat); - - println!("removing /test..."); - println!(); - - file_rm - }) - .map(|_| println!("done!")) - .map_err(|e| eprintln!("{}", e)) - ; - - #[cfg(feature = "hyper")] + let fut = mkdir + .and_then(|_| { + println!("making dirs /test/does/not/exist/yet..."); + println!(); + + mkdir_recursive + }) + .and_then(|_| { + println!("getting status of /test/does..."); + println!(); + + file_stat + }) + .and_then(|stat| { + print_stat(stat); + + println!("writing source file to /test/mfs.rs"); + println!(); + + file_write + }) + .and_then(|_| file_write_stat) + .and_then(|stat| { + print_stat(stat); + + println!("removing /test..."); + println!(); + + file_rm + }) + .map(|_| println!("done!")) + .map_err(|e| eprintln!("{}", e)); + + #[cfg(feature = "hyper")] hyper::rt::run(fut); #[cfg(feature = "actix")] actix_web::actix::run(|| { diff --git a/ipfs-api/examples/ping_peer.rs b/ipfs-api/examples/ping_peer.rs index c60e895..af48f69 100644 --- a/ipfs-api/examples/ping_peer.rs +++ b/ipfs-api/examples/ping_peer.rs @@ -62,7 +62,7 @@ fn main() { }) .map_err(|e| eprintln!("{}", e)); - #[cfg(feature = "hyper")] + #[cfg(feature = "hyper")] hyper::rt::run(req); #[cfg(feature = "actix")] actix_web::actix::run(|| { diff --git a/ipfs-api/src/client.rs b/ipfs-api/src/client.rs index 5e1e9f5..69411ee 100644 --- a/ipfs-api/src/client.rs +++ b/ipfs-api/src/client.rs @@ -22,14 +22,18 @@ use http::StatusCode; use hyper::client::{Client, HttpConnector}; #[cfg(feature = "hyper")] use hyper_multipart::client::multipart; +use multiaddr::{AddrComponent, ToMultiaddr}; use read::{JsonLineDecoder, LineDecoder, StreamReader}; use request::{self, ApiRequest}; use response::{self, Error}; use serde::{Deserialize, Serialize}; use serde_json; -use std::io::Read; -use std::net::SocketAddr; -use std::path::{Path, PathBuf}; +use std::{ + fs, + io::Read, + net::{IpAddr, SocketAddr}, + path::{Path, PathBuf}, +}; use tokio_codec::{Decoder, FramedRead}; /// A response returned by the HTTP client. @@ -70,16 +74,8 @@ impl Default for IpfsClient { /// If not found, tries to connect to `localhost:5001`. /// fn default() -> IpfsClient { - use multiaddr::{AddrComponent, ToMultiaddr}; - use std::fs; - use std::net::IpAddr; - dirs::home_dir() - .map(|mut home_dir| { - home_dir.push(".ipfs"); - home_dir.push("api"); - home_dir - }) + .map(|home_dir| home_dir.join(".ipfs").join("api")) .and_then(|multiaddr_path| fs::read_to_string(&multiaddr_path).ok()) .and_then(|multiaddr_str| multiaddr_str.to_multiaddr().ok()) .and_then(|multiaddr| { diff --git a/ipfs-api/src/lib.rs b/ipfs-api/src/lib.rs index 64ea2f4..22568d8 100644 --- a/ipfs-api/src/lib.rs +++ b/ipfs-api/src/lib.rs @@ -14,145 +14,170 @@ //! //! ```toml //! [dependencies] -//! ipfs-api = "0.5.0-alpha2" +//! ipfs-api = "0.5.1" +//! ``` +//! +//! You can use `actix-web` as a backend instead of `hyper`. +//! +//! ```toml +//! [dependencies] +//! ipfs-api = { version = "0.5.1", features = ["actix"], default-features = false } +//! ``` +//! +//! ## Examples +//! +//! ### Writing a file to IPFS +//! +//! #### With Hyper +//! +//! ```no_run +//! # extern crate hyper; +//! # extern crate ipfs_api; +//! # +//! use hyper::rt::Future; +//! use ipfs_api::IpfsClient; +//! use std::io::Cursor; +//! +//! # fn main() { +//! let client = IpfsClient::default(); +//! let data = Cursor::new("Hello World!"); +//! +//! let req = client +//! .add(data) +//! .map(|res| { +//! println!("{}", res.hash); +//! }) +//! .map_err(|e| eprintln!("{}", e)); +//! +//! hyper::rt::run(req); +//! # } +//! ``` +//! +//! #### With Actix +//! +//! ```no_run +//! # extern crate actix_web; +//! # extern crate futures; +//! # extern crate ipfs_api; +//! # +//! use futures::future::Future; +//! use ipfs_api::IpfsClient; +//! use std::io::Cursor; +//! +//! # fn main() { +//! let client = IpfsClient::default(); +//! let data = Cursor::new("Hello World!"); +//! +//! let req = client +//! .add(data) +//! .map(|res| { +//! println!("{}", res.hash); +//! }) +//! .map_err(|e| eprintln!("{}", e)); +//! +//! actix_web::actix::run(|| { +//! req.then(|_| { +//! actix_web::actix::System::current().stop(); +//! Ok(()) +//! }) +//! }); +//! # } +//! ``` +//! +//! ### Reading a file from IPFS +//! +//! #### With Hyper +//! +//! ```no_run +//! # extern crate futures; +//! # extern crate hyper; +//! # extern crate ipfs_api; +//! # +//! use futures::{Future, Stream}; +//! use ipfs_api::IpfsClient; +//! use std::io::{self, Write}; +//! +//! # fn main() { +//! let client = IpfsClient::default(); +//! +//! let req = client +//! .get("/test/file.json") +//! .concat2() +//! .map(|res| { +//! let out = io::stdout(); +//! let mut out = out.lock(); +//! +//! out.write_all(&res).unwrap(); +//! }) +//! .map_err(|e| eprintln!("{}", e)); +//! +//! hyper::rt::run(req); +//! # } +//! ``` +//! +//! #### With Actix +//! +//! ```no_run +//! # extern crate futures; +//! # extern crate actix_web; +//! # extern crate ipfs_api; +//! # +//! use futures::{Future, Stream}; +//! use ipfs_api::IpfsClient; +//! use std::io::{self, Write}; +//! +//! # fn main() { +//! let client = IpfsClient::default(); +//! +//! let req = client +//! .get("/test/file.json") +//! .concat2() +//! .map(|res| { +//! let out = io::stdout(); +//! let mut out = out.lock(); +//! +//! out.write_all(&res).unwrap(); +//! }) +//! .map_err(|e| eprintln!("{}", e)); +//! +//! actix_web::actix::run(|| { +//! req.then(|_| { +//! actix_web::actix::System::current().stop(); +//! Ok(()) +//! }) +//! }); +//! # } +//! ``` +//! +//! ### Additional Examples +//! +//! There are also a bunch of examples included in the project, which +//! I used for testing +//! +//! For a list of examples, run: +//! +//! ```sh +//! $ cargo run --example +//! ``` +//! +//! You can run any of the examples with cargo: +//! +//! ```sh +//! $ cargo run -p ipfs-api --example add_file +//! ``` +//! +//! To run an example with the `actix-web` backend, use: +//! +//! ```sh +//! $ cargo run -p ipfs-api --features actix --no-default-features --example add_file //! ``` //! #[cfg(feature = "actix")] extern crate actix_multipart_rfc7578 as actix_multipart; - -/// ## Examples -/// -/// Write a file to IPFS: -/// -/// ```no_run -/// # extern crate actix_web; -/// # extern crate futures; -/// # extern crate ipfs_api; -/// # -/// use futures::future::Future; -/// use ipfs_api::IpfsClient; -/// use std::io::Cursor; -/// -/// # fn main() { -/// let client = IpfsClient::default(); -/// let data = Cursor::new("Hello World!"); -/// -/// let req = client -/// .add(data) -/// .map(|res| { -/// println!("{}", res.hash); -/// }) -/// .map_err(|e| eprintln!("{}", e)); -/// -/// tokio::runtime::current_thread::run(req); -/// # } -/// ``` -/// -/// Read a file from IPFS: -/// -/// ```no_run -/// # extern crate futures; -/// # extern crate actix_web; -/// # extern crate ipfs_api; -/// # -/// use futures::{Future, Stream}; -/// use ipfs_api::IpfsClient; -/// use std::io::{self, Write}; -/// -/// # fn main() { -/// let client = IpfsClient::default(); -/// -/// let req = client -/// .get("/test/file.json") -/// .concat2() -/// .map(|res| { -/// let out = io::stdout(); -/// let mut out = out.lock(); -/// -/// out.write_all(&res).unwrap(); -/// }) -/// .map_err(|e| eprintln!("{}", e)); -/// -/// tokio::runtime::current_thread::run(req); -/// # } -/// ``` -/// -/// There are also a bunch of examples included in the project, which -/// I used for testing -/// -/// You can run any of the examples with cargo: -/// -/// ```sh -/// $ cargo run -p ipfs-api --example add_file -/// ``` #[cfg(feature = "actix")] extern crate actix_web; -/// ## Examples -/// -/// Write a file to IPFS: -/// -/// ```no_run -/// # extern crate hyper; -/// # extern crate ipfs_api; -/// # -/// use hyper::rt::Future; -/// use ipfs_api::IpfsClient; -/// use std::io::Cursor; -/// -/// # fn main() { -/// let client = IpfsClient::default(); -/// let data = Cursor::new("Hello World!"); -/// -/// let req = client -/// .add(data) -/// .map(|res| { -/// println!("{}", res.hash); -/// }) -/// .map_err(|e| eprintln!("{}", e)); -/// -/// hyper::rt::run(req); -/// # } -/// ``` -/// -/// Read a file from IPFS: -/// -/// ```no_run -/// # extern crate futures; -/// # extern crate hyper; -/// # extern crate ipfs_api; -/// # -/// use futures::{Future, Stream}; -/// use ipfs_api::IpfsClient; -/// use std::io::{self, Write}; -/// -/// # fn main() { -/// let client = IpfsClient::default(); -/// -/// let req = client -/// .get("/test/file.json") -/// .concat2() -/// .map(|res| { -/// let out = io::stdout(); -/// let mut out = out.lock(); -/// -/// out.write_all(&res).unwrap(); -/// }) -/// .map_err(|e| eprintln!("{}", e)); -/// -/// hyper::rt::run(req); -/// # } -/// ``` -/// -/// There are also a bunch of examples included in the project, which -/// I used for testing -/// -/// You can run any of the examples with cargo: -/// -/// ```sh -/// $ cargo run -p ipfs-api --example add_file -/// ``` #[cfg(feature = "hyper")] extern crate hyper; #[cfg(feature = "hyper")] diff --git a/ipfs-cli/Cargo.toml b/ipfs-cli/Cargo.toml index e0a11e6..eb9466f 100644 --- a/ipfs-cli/Cargo.toml +++ b/ipfs-cli/Cargo.toml @@ -3,12 +3,12 @@ name = "ipfs-cli" description = "A CLI to interact with IPFS" authors = ["Ferris Tseng "] repository = "https://github.com/ferristseng/rust-ipfs-api" -version = "0.4.0" +version = "0.4.1" readme = "../README.md" license = "MIT OR Apache-2.0" [dependencies] -clap = "2.27" +clap = "2.32" futures = "0.1" hyper = "0.12" ipfs-api = { path = "../ipfs-api" } -- cgit v1.2.3