summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--.travis.yml5
-rw-r--r--README.md66
-rw-r--r--README.tpl20
-rw-r--r--ipfs-api/Cargo.toml14
-rw-r--r--ipfs-api/examples/get_version.rs26
-rw-r--r--ipfs-api/examples/pubsub.rs2
-rw-r--r--ipfs-api/src/client.rs1278
-rw-r--r--ipfs-api/src/header.rs11
-rw-r--r--ipfs-api/src/lib.rs67
-rw-r--r--ipfs-api/src/request/pin.rs6
-rw-r--r--ipfs-api/src/request/pubsub.rs6
-rw-r--r--ipfs-api/src/response/mod.rs2
13 files changed, 1325 insertions, 179 deletions
diff --git a/.gitignore b/.gitignore
index 6aa1064..a781dd1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
/target/
+**/target/
**/*.rs.bk
Cargo.lock
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..b4f863c
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,5 @@
+language: rust
+rust:
+ - stable
+ - beta
+ - nightly
diff --git a/README.md b/README.md
index fdeaac3..a544ef5 100644
--- a/README.md
+++ b/README.md
@@ -1,23 +1,65 @@
-## Rust IPFS API Library
+# ipfs-api
+
+[![Travis](https://img.shields.io/travis/ferristseng/rust-ipfs-api.svg)](https://travis-ci.org/ferristseng/rust-ipfs-api)
+[![Crates.io](https://img.shields.io/crates/v/ipfs-api.svg)](https://crates.io/crates/ipfs-api)
+[![Docs.rs](https://docs.rs/ipfs-api/badge.svg)](https://docs.rs/ipfs-api/)
+
+Rust library for connecting to the IPFS HTTP API using tokio.
+
+### Usage
```toml
[dependencies]
-ipfs-api = "0.4.0"
+ipfs-api = "0.4.0-alpha"
```
-### Goals
+### Examples
+
+Write a file to IPFS:
- * Provide a full implementation of the HTTP API specification described here: https://ipfs.io/docs/api/.
- * Write idiomatic rust, and make use of rust's memory safety features.
- * Provide support for `go-ipfs 0.4.*`, with possible backwards compatibility features.
- * Feature parity with the `go-ipfs` cli.
- * Provide cross platform support for Linux, OSX, and Windows.
+```rust
+#
+use ipfs_api::IpfsClient;
+use std::io::Cursor;
+use tokio_core::reactor::Core;
+
+let mut core = Core::new().unwrap();
+let client = IpfsClient::default(&core.handle());
+let data = Cursor::new("Hello World!");
+
+let req = client.add(data);
+let res = core.run(req).unwrap();
+
+println!("{}", res.hash);
+```
-#### Maybe (?)
+Read a file from IPFS:
- * Add integration tests for the `go-ipfs` implementation, and `js-ipfs` implementation of the ipfs spec.
- * Explore a higher level API for interacting with IPFS.
- * File system abstraction
+```rust
+#
+use futures::stream::Stream;
+use ipfs_api::IpfsClient;
+use std::io::{self, Write};
+use tokio_core::reactor::Core;
+
+let mut core = Core::new().unwrap();
+let client = IpfsClient::default(&core.handle());
+
+let req = client.get("/test/file.json").concat2();
+let res = core.run(req).unwrap();
+let out = io::stdout();
+let mut out = out.lock();
+
+out.write_all(&res).unwrap();
+```
+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
+```
## License
diff --git a/README.tpl b/README.tpl
new file mode 100644
index 0000000..7242565
--- /dev/null
+++ b/README.tpl
@@ -0,0 +1,20 @@
+# {{crate}}
+
+[![Travis](https://img.shields.io/travis/ferristseng/rust-ipfs-api.svg)](https://travis-ci.org/ferristseng/rust-ipfs-api)
+[![Crates.io](https://img.shields.io/crates/v/ipfs-api.svg)](https://crates.io/crates/ipfs-api)
+[![Docs.rs](https://docs.rs/ipfs-api/badge.svg)](https://docs.rs/ipfs-api/)
+
+{{readme}}
+
+## License
+
+Licensed under either of
+
+ * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
+ * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
+
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
diff --git a/ipfs-api/Cargo.toml b/ipfs-api/Cargo.toml
index 4670e40..798a598 100644
--- a/ipfs-api/Cargo.toml
+++ b/ipfs-api/Cargo.toml
@@ -1,15 +1,23 @@
[package]
name = "ipfs-api"
-version = "0.4.0"
-license = "MIT OR Apache-2.0"
+description = "Implementation of an IPFS HTTP API client"
authors = ["Ferris Tseng <ferristseng@fastmail.fm>"]
+documentation = "https://docs.rs/ipfs-api"
+keywords = ["ipfs"]
+categories = ["filesystem", "web-programming"]
+version = "0.4.0-alpha"
+readme = "../README.md"
+license = "MIT OR Apache-2.0"
+
+[badges]
+travis-ci = { repository = "ferristseng/rust-ipfs-api" }
[dependencies]
bytes = "0.4"
error-chain = "0.11"
futures = "0.1"
hyper = "0.11"
-hyper-multipart-rfc7578 = { git = "https://github.com/ferristseng/rust-hyper-multipart-rfc7578" }
+hyper-multipart-rfc7578 = "0.1.0-alpha"
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
diff --git a/ipfs-api/examples/get_version.rs b/ipfs-api/examples/get_version.rs
index 257d1c7..deea4e6 100644
--- a/ipfs-api/examples/get_version.rs
+++ b/ipfs-api/examples/get_version.rs
@@ -6,11 +6,9 @@
// copied, modified, or distributed except according to those terms.
//
-extern crate futures;
extern crate ipfs_api;
extern crate tokio_core;
-use futures::stream::Stream;
use ipfs_api::IpfsClient;
use tokio_core::reactor::Core;
@@ -25,28 +23,4 @@ fn main() {
let version = core.run(req).expect("expected a valid response");
println!("version: {:?}", version.version);
-
- let req = client.refs_local();
- println!(
- "{:?}",
- core.run(req.for_each(|res| Ok(println!("{:?}", res))))
- );
-
- let req = client.diag_sys();
- println!("{}", core.run(req).expect("response"));
-
- let req = client.dns("ipfs.io", false);
- let dns = core.run(req).expect("response");
- println!("{:?}", dns);
-
- let req = client.file_ls(&dns.path[..]);
- println!("{:?}", core.run(req).expect("response"));
-
- /*
- let req = client.dht_get("QmRJijhiMxQgn7bFP4cBsarHsGMM8g9fLDEE3WtkTXr4Hr");
- println!(
- "{:?}",
- core.run(req.for_each(|res| Ok(println!("{:?}", res))))
- );
- */
}
diff --git a/ipfs-api/examples/pubsub.rs b/ipfs-api/examples/pubsub.rs
index ed01b0b..59f8ce7 100644
--- a/ipfs-api/examples/pubsub.rs
+++ b/ipfs-api/examples/pubsub.rs
@@ -60,7 +60,7 @@ fn main() {
{
let mut event_loop = Core::new().expect("expected event loop");
let client = get_client(&event_loop.handle());
- let req = client.pubsub_sub(TOPIC, &None);
+ let req = client.pubsub_sub(TOPIC, false);
println!("");
println!("waiting for messages on ({})...", TOPIC);
diff --git a/ipfs-api/src/client.rs b/ipfs-api/src/client.rs
index 387d48d..c5fb1bd 100644
--- a/ipfs-api/src/client.rs
+++ b/ipfs-api/src/client.rs
@@ -6,8 +6,8 @@
// copied, modified, or distributed except according to those terms.
//
-use futures::Stream;
use futures::future::{Future, IntoFuture};
+use futures::stream::{self, Stream};
use header::Trailer;
use read::{JsonLineDecoder, LineDecoder, StreamReader};
use request::{self, ApiRequest};
@@ -22,7 +22,7 @@ use tokio_core::reactor::Handle;
use tokio_io::codec::{Decoder, FramedRead};
-/// A future response returned by the reqwest HTTP client.
+/// A response returned by the HTTP client.
///
type AsyncResponse<T> = Box<Future<Item = T, Error = Error>>;
@@ -145,58 +145,77 @@ impl IpfsClient {
Box::new(stream)
}
- /// Sends a request and returns the raw response.
- ///
- /// Methods prefixed with `send_` work on a raw reqwest `RequestBuilder`
- /// instance.
- ///
- fn send_request(&self, req: Request<multipart::Body>) -> AsyncResponse<(StatusCode, Chunk)> {
- let res = self.client
- .request(req)
- .and_then(|res| {
- let status = res.status();
-
- res.body().concat2().map(move |chunk| (status, chunk))
- })
- .from_err();
-
- Box::new(res)
- }
-
- /// Sends a request and deserializes the response into Json.
- ///
- /// Methods prefixed with `send_` work on a raw reqwest `RequestBuilder`
- /// instance.
+ /// Generates a request, and returns the unprocessed response future.
///
- fn send_request_json<Res>(&self, req: Request<multipart::Body>) -> AsyncResponse<Res>
+ fn request_raw<Req>(
+ &self,
+ req: &Req,
+ form: Option<multipart::Form>,
+ ) -> AsyncResponse<(StatusCode, Chunk)>
where
- for<'de> Res: 'static + Deserialize<'de>,
+ Req: ApiRequest + Serialize,
{
- let res = self.send_request(req).into_future().and_then(
- |(status, chunk)| {
- IpfsClient::process_json_response(status, chunk)
- },
- );
-
- Box::new(res)
+ match self.build_base_request(req, form) {
+ Ok(req) => {
+ let res = self.client
+ .request(req)
+ .and_then(|res| {
+ let status = res.status();
+
+ res.body().concat2().map(move |chunk| (status, chunk))
+ })
+ .from_err();
+
+ Box::new(res)
+ }
+ Err(e) => Box::new(Err(e).into_future()),
+ }
}
- /// Generates a request, and returns the unprocessed response future.
+ /// Generic method for making a request that expects back a streaming
+ /// response.
///
- fn request_raw<Req>(
+ fn request_stream<Req, Res, F>(
&self,
req: &Req,
form: Option<multipart::Form>,
- ) -> AsyncResponse<(StatusCode, Chunk)>
+ process: F,
+ ) -> AsyncStreamResponse<Res>
where
Req: ApiRequest + Serialize,
+ Res: 'static,
+ F: 'static + Fn(hyper::Response) -> AsyncStreamResponse<Res>,
{
- let res = self.build_base_request(req, form)
- .map(|req| self.send_request(req))
- .into_future()
- .flatten();
+ match self.build_base_request(req, form) {
+ Ok(req) => {
+ let res = self.client
+ .request(req)
+ .from_err()
+ .map(move |res| {
+ let stream: Box<Stream<Item = Res, Error = _>> = match res.status() {
+ StatusCode::Ok => process(res),
+
+ // If the server responded with an error status code, the body
+ // still needs to be read so an error can be built. This block will
+ // read the entire body stream, then immediately return an error.
+ //
+ _ => Box::new(
+ res.body()
+ .concat2()
+ .from_err()
+ .and_then(|chunk| Err(Self::build_error_from_body(chunk)))
+ .into_stream(),
+ ),
+ };
- Box::new(res)
+ stream
+ })
+ .flatten_stream();
+
+ Box::new(res)
+ }
+ Err(e) => Box::new(stream::once(Err(e))),
+ }
}
/// Generic method for making a request to the Ipfs server, and getting
@@ -207,10 +226,9 @@ impl IpfsClient {
Req: ApiRequest + Serialize,
for<'de> Res: 'static + Deserialize<'de>,
{
- let res = self.build_base_request(req, form)
- .map(|req| self.send_request_json(req))
- .into_future()
- .flatten();
+ let res = self.request_raw(req, form).and_then(|(status, chunk)| {
+ IpfsClient::process_json_response(status, chunk)
+ });
Box::new(res)
}
@@ -249,6 +267,7 @@ impl IpfsClient {
Box::new(res)
}
+
/// Generic method for making a request to the Ipfs server, and getting
/// back a raw stream of bytes.
///
@@ -260,41 +279,13 @@ impl IpfsClient {
where
Req: ApiRequest + Serialize,
{
- let res = self.build_base_request(req, form)
- .map(|req| self.client.request(req).from_err())
- .into_future()
- .flatten()
- .map(|res| {
- let stream: Box<Stream<Item = Chunk, Error = _>> = match res.status() {
- // If the server responded OK, the data can be streamed back.
- //
- StatusCode::Ok => Box::new(res.body().map(|chunk| chunk).from_err()),
-
- // If the server responded with an error status code, the body
- // still needs to be read so an error can be built. This block will
- // read the entire body stream, then immediately return an error.
- //
- _ => Box::new(
- res.body()
- .concat2()
- .from_err()
- .and_then(|chunk| Err(Self::build_error_from_body(chunk)))
- .into_stream(),
- ),
-
- };
-
- stream
- })
- .flatten_stream();
-
- Box::new(res)
+ self.request_stream(req, form, |res| Box::new(res.body().from_err()))
}
/// Generic method to return a streaming response of deserialized json
/// objects delineated by new line separators.
///
- fn request_stream<Req, Res>(
+ fn request_stream_json<Req, Res>(
&self,
req: &Req,
form: Option<multipart::Form>,
@@ -303,50 +294,48 @@ impl IpfsClient {
Req: ApiRequest + Serialize,
for<'de> Res: 'static + Deserialize<'de>,
{
- let res = self.build_base_request(req, form)
- .map(|req| self.client.request(req).from_err())
- .into_future()
- .flatten()
- .map(|res| {
- let stream: Box<Stream<Item = Res, Error = _>> = match res.status() {
- StatusCode::Ok => {
- let parse_stream_error = if let Some(trailer) = res.headers().get() {
- // Response has the Trailer header set. The StreamError trailer
- // is used to indicate that there was an error while streaming
- // data with Ipfs.
- //
- match trailer {
- &Trailer::StreamError => true,
- }
- } else {
- false
- };
-
- Box::new(IpfsClient::process_stream_response(
- res,
- JsonLineDecoder::new(parse_stream_error),
- ))
- }
- _ => Box::new(
- res.body()
- .concat2()
- .from_err()
- .and_then(|chunk| Err(Self::build_error_from_body(chunk)))
- .into_stream(),
- ),
- };
-
- stream
- })
- .flatten_stream();
-
- Box::new(res)
+ self.request_stream(req, form, |res| {
+ let parse_stream_error = if let Some(trailer) = res.headers().get() {
+ // Response has the Trailer header set. The StreamError trailer
+ // is used to indicate that there was an error while streaming
+ // data with Ipfs.
+ //
+ match trailer {
+ &Trailer::StreamError => true,
+ }
+ } else {
+ false
+ };
+
+ Box::new(IpfsClient::process_stream_response(
+ res,
+ JsonLineDecoder::new(parse_stream_error),
+ ))
+ })
}
}
impl IpfsClient {
/// Add file to Ipfs.
///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// # extern crate ipfs_api;
+ /// # extern crate tokio_core;
+ /// #
+ /// use ipfs_api::IpfsClient;
+ /// use std::io::Cursor;
+ /// use tokio_core::reactor::Core;
+ ///
+ /// # fn main() {
+ /// let mut core = Core::new().unwrap();
+ /// let client = IpfsClient::default(&core.handle());
+ /// let data = Cursor::new("Hello World!");
+ /// let req = client.add(data);
+ /// # }
+ /// ```
+ ///
#[inline]
pub fn add<R>(&self, data: R) -> AsyncResponse<response::AddResponse>
where
@@ -361,6 +350,22 @@ impl IpfsClient {
/// Returns the current ledger for a peer.
///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// # extern crate ipfs_api;
+ /// # extern crate tokio_core;
+ /// #
+ /// use ipfs_api::IpfsClient;
+ /// use tokio_core::reactor::Core;
+ ///
+ /// # fn main() {
+ /// let mut core = Core::new().unwrap();
+ /// let client = IpfsClient::default(&core.handle());
+ /// let req = client.bitswap_ledger("QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ");
+ /// # }
+ /// ```
+ ///
#[inline]
pub fn bitswap_ledger(&self, peer: &str) -> AsyncResponse<response::BitswapLedgerResponse> {
self.request(&request::BitswapLedger { peer }, None)
@@ -368,6 +373,22 @@ impl IpfsClient {
/// Returns some stats about the bitswap agent.
///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// # extern crate ipfs_api;
+ /// # extern crate tokio_core;
+ /// #
+ /// use ipfs_api::IpfsClient;
+ /// use tokio_core::reactor::Core;
+ ///
+ /// # fn main() {
+ /// let mut core = Core::new().unwrap();
+ /// let client = IpfsClient::default(&core.handle());
+ /// let req = client.bitswap_stat();
+ /// # }
+ /// ```
+ ///
#[inline]
pub fn bitswap_stat(&self) -> AsyncResponse<response::BitswapStatResponse> {
self.request(&request::BitswapStat, None)
@@ -375,6 +396,22 @@ impl IpfsClient {
/// Remove a given block from your wantlist.
///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// # extern crate ipfs_api;
+ /// # extern crate tokio_core;
+ /// #
+ /// use ipfs_api::IpfsClient;
+ /// use tokio_core::reactor::Core;
+ ///
+ /// # fn main() {
+ /// let mut core = Core::new().unwrap();
+ /// let client = IpfsClient::default(&core.handle());
+ /// let req = client.bitswap_unwant("QmXdNSQx7nbdRvkjGCEQgVjVtVwsHvV8NmV2a8xzQVwuFA");
+ /// # }
+ /// ```
+ ///
#[inline]
pub fn bitswap_unwant(&self, key: &str) -> AsyncResponse<response::BitswapUnwantResponse> {
self.request_empty(&request::BitswapUnwant { key }, None)
@@ -382,6 +419,22 @@ impl IpfsClient {
/// Shows blocks on the wantlist for you or the specified peer.
///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// # extern crate ipfs_api;
+ /// # extern crate tokio_core;
+ /// #
+ /// use ipfs_api::IpfsClient;
+ /// use tokio_core::reactor::Core;
+ ///
+ /// # fn main() {
+ /// let mut core = Core::new().unwrap();
+ /// let client = IpfsClient::default(&core.handle());
+ /// let req = client.bitswap_wantlist(Some("QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ"));
+ /// # }
+ /// ```
+ ///
#[inline]
pub fn bitswap_wantlist(
&self,
@@ -392,6 +445,25 @@ impl IpfsClient {
/// Gets a raw IPFS block.
///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// # extern crate futures;
+ /// # extern crate ipfs_api;
+ /// # extern crate tokio_core;
+ /// #
+ /// use futures::stream::Stream;
+ /// use ipfs_api::IpfsClient;
+ /// use tokio_core::reactor::Core;
+ ///
+ /// # fn main() {
+ /// let mut core = Core::new().unwrap();
+ /// let client = IpfsClient::default(&core.handle());
+ /// let hash = "QmXdNSQx7nbdRvkjGCEQgVjVtVwsHvV8NmV2a8xzQVwuFA";
+ /// let req = client.block_get(hash).concat2();
+ /// # }
+ /// ```
+ ///
#[inline]
pub fn block_get(&self, hash: &str) -> AsyncStreamResponse<Chunk> {
self.request_stream_bytes(&request::BlockGet { hash }, None)
@@ -399,6 +471,24 @@ impl IpfsClient {
/// Store input as an IPFS block.
///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// # extern crate ipfs_api;
+ /// # extern crate tokio_core;
+ /// #
+ /// use ipfs_api::IpfsClient;
+ /// use std::io::Cursor;
+ /// use tokio_core::reactor::Core;
+ ///
+ /// # fn main() {
+ /// let mut core = Core::new().unwrap();
+ /// let client = IpfsClient::default(&core.handle());
+ /// let data = Cursor::new("Hello World!");
+ /// let req = client.block_put(data);
+ /// # }
+ /// ```
+ ///
#[inline]
pub fn block_put<R>(&self, data: R) -> AsyncResponse<response::BlockPutResponse>
where
@@ -413,6 +503,22 @@ impl IpfsClient {
/// Removes an IPFS block.
///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// # extern crate ipfs_api;
+ /// # extern crate tokio_core;
+ /// #
+ /// use ipfs_api::IpfsClient;
+ /// use tokio_core::reactor::Core;
+ ///
+ /// # fn main() {
+ /// let mut core = Core::new().unwrap();
+ /// let client = IpfsClient::default(&core.handle());
+ /// let req = client.block_rm("QmXdNSQx7nbdRvkjGCEQgVjVtVwsHvV8NmV2a8xzQVwuFA");
+ /// # }
+ /// ```
+ ///
#[inline]
pub fn block_rm(&self, hash: &str) -> AsyncResponse<response::BlockRmResponse> {
self.request(&request::BlockRm { hash }, None)
@@ -420,6 +526,22 @@ impl IpfsClient {
/// Prints information about a raw IPFS block.
///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// # extern crate ipfs_api;
+ /// # extern crate tokio_core;
+ /// #
+ /// use ipfs_api::IpfsClient;
+ /// use tokio_core::reactor::Core;
+ ///
+ /// # fn main() {
+ /// let mut core = Core::new().unwrap();
+ /// let client = IpfsClient::default(&core.handle());
+ /// let req = client.block_stat("QmXdNSQx7nbdRvkjGCEQgVjVtVwsHvV8NmV2a8xzQVwuFA");
+ /// # }
+ /// ```
+ ///
#[inline]
pub fn block_stat(&self, hash: &str) -> AsyncResponse<response::BlockStatResponse> {
self.request(&request::BlockStat { hash }, None)
@@ -427,6 +549,22 @@ impl IpfsClient {
/// Add default peers to the bootstrap list.
///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// # extern crate ipfs_api;
+ /// # extern crate tokio_core;
+ /// #
+ /// use ipfs_api::IpfsClient;
+ /// use tokio_core::reactor::Core;
+ ///
+ /// # fn main() {
+ /// let mut core = Core::new().unwrap();
+ /// let client = IpfsClient::default(&core.handle());
+ /// let req = client.bootstrap_add_default();
+ /// # }
+ /// ```
+ ///
#[inline]
pub fn bootstrap_add_default(&self) -> AsyncResponse<response::BootstrapAddDefaultResponse> {
self.request(&request::BootstrapAddDefault, None)
@@ -434,6 +572,22 @@ impl IpfsClient {
/// Lists peers in bootstrap list.
///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// # extern crate ipfs_api;
+ /// # extern crate tokio_core;
+ /// #
+ /// use ipfs_api::IpfsClient;
+ /// use tokio_core::reactor::Core;
+ ///
+ /// # fn main() {
+ /// let mut core = Core::new().unwrap();
+ /// let client = IpfsClient::default(&core.handle());
+ /// let req = client.bootstrap_list();
+ /// # }
+ /// ```
+ ///
#[inline]
pub fn bootstrap_list(&self) -> AsyncResponse<response::BootstrapListResponse> {
self.request(&request::BootstrapList, None)
@@ -441,6 +595,22 @@ impl IpfsClient {
/// Removes all peers in bootstrap list.
///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// # extern crate ipfs_api;
+ /// # extern crate tokio_core;
+ /// #
+ /// use ipfs_api::IpfsClient;
+ /// use tokio_core::reactor::Core;
+ ///
+ /// # fn main() {
+ /// let mut core = Core::new().unwrap();
+ /// let client = IpfsClient::default(&core.handle());
+ /// let req = client.bootstrap_rm_all();
+ /// # }
+ /// ```
+ ///
#[inline]
pub fn bootstrap_rm_all(&self) -> AsyncResponse<response::BootstrapRmAllResponse> {
self.request(&request::BootstrapRmAll, None)
@@ -448,6 +618,25 @@ impl IpfsClient {
/// Returns the contents of an Ipfs object.
///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// # extern crate futures;
+ /// # extern crate ipfs_api;
+ /// # extern crate tokio_core;
+ /// #
+ /// use futures::stream::Stream;
+ /// use ipfs_api::IpfsClient;
+ /// use tokio_core::reactor::Core;
+ ///
+ /// # fn main() {
+ /// let mut core = Core::new().unwrap();
+ /// let client = IpfsClient::default(&core.handle());
+ /// let hash = "QmXdNSQx7nbdRvkjGCEQgVjVtVwsHvV8NmV2a8xzQVwuFA";
+ /// let req = client.cat(hash).concat2();
+ /// # }
+ /// ```
+ ///
#[inline]
pub fn cat(&self, path: &str) -> AsyncStreamResponse<Chunk> {
self.request_stream_bytes(&request::Cat { path }, None)
@@ -455,6 +644,20 @@ impl IpfsClient {
/// List available commands that the server accepts.
///
+ /// ```no_run
+ /// # extern crate ipfs_api;
+ /// # extern crate tokio_core;
+ /// #
+ /// use ipfs_api::IpfsClient;
+ /// use tokio_core::reactor::Core;
+ ///
+ /// # fn main() {
+ /// let mut core = Core::new().unwrap();
+ /// let client = IpfsClient::default(&core.handle());
+ /// let req = client.commands();
+ /// # }
+ /// ```
+ ///
#[inline]
pub fn commands(&self) -> AsyncResponse<response::CommandsResponse> {
self.request(&request::Commands, None)
@@ -462,6 +665,20 @@ impl IpfsClient {
/// Opens the config file for editing (on the server).
///
+ /// ```no_run
+ /// # extern crate ipfs_api;
+ /// # extern crate tokio_core;
+ /// #
+ /// use ipfs_api::IpfsClient;
+ /// use tokio_core::reactor::Core;
+ ///
+ /// # fn main() {
+ /// let mut core = Core::new().unwrap();
+ /// let client = IpfsClient::default(&core.handle());
+ /// let req = client.config_edit();
+ /// # }
+ /// ```
+ ///
#[inline]
pub fn config_edit(&self) -> AsyncResponse<response::ConfigEditResponse> {
self.request(&request::ConfigEdit, None)
@@ -469,6 +686,22 @@ impl IpfsClient {
/// Replace the config file.
///
+ /// ```no_run
+ /// # extern crate ipfs_api;
+ /// # extern crate tokio_core;
+ /// #
+ /// use ipfs_api::IpfsClient;
+ /// use std::io::Cursor;
+ /// use tokio_core::reactor::Core;
+ ///
+ /// # fn main() {
+ /// let mut core = Core::new().unwrap();
+ /// let client = IpfsClient::default(&core.handle());
+ /// let config = Cursor::new("{..json..}");
+ /// let req = client.config_replace(config);
+ /// # }
+ /// ```
+ ///
#[inline]
pub fn config_replace<R>(&self, data: R) -> AsyncResponse<response::ConfigReplaceResponse>
where
@@ -485,6 +718,20 @@ impl IpfsClient {
///
/// Returns an unparsed json string, due to an unclear spec.
///
+ /// ```no_run
+ /// # extern crate ipfs_api;
+ /// # extern crate tokio_core;
+ /// #
+ /// use ipfs_api::IpfsClient;
+ /// use tokio_core::reactor::Core;
+ ///
+ /// # fn main() {
+ /// let mut core = Core::new().unwrap();
+ /// let client = IpfsClient::default(&core.handle());
+ /// let req = client.config_show();
+ /// # }
+ /// ```
+ ///
#[inline]
pub fn config_show(&self) -> AsyncResponse<response::ConfigShowResponse> {
self.request_string(&request::ConfigShow, None)
@@ -492,6 +739,20 @@ impl IpfsClient {
/// Returns information about a dag node in Ipfs.
///
+ /// ```no_run
+ /// # extern crate ipfs_api;
+ /// # extern crate tokio_core;
+ /// #
+ /// use ipfs_api::IpfsClient;
+ /// use tokio_core::reactor::Core;
+ ///
+ /// # fn main() {
+ /// let mut core = Core::new().unwrap();
+ /// let client = IpfsClient::default(&core.handle());
+ /// let req = client.dag_get("QmXdNSQx7nbdRvkjGCEQgVjVtVwsHvV8NmV2a8xzQVwuFA");
+ /// # }
+ /// ```
+ ///
#[inline]
pub fn dag_get(&self, path: &str) -> AsyncResponse<response::DagGetResponse> {
self.request(&request::DagGet { path }, None)
@@ -516,48 +777,163 @@ impl IpfsClient {
/// Query the DHT for all of the multiaddresses associated with a Peer ID.
///
+ /// ```no_run
+ /// # extern crate futures;
+ /// # extern crate ipfs_api;
+ /// # extern crate tokio_core;
+ /// #
+ /// use futures::stream::Stream;
+ /// use ipfs_api::IpfsClient;
+ /// use tokio_core::reactor::Core;
+ ///
+ /// # fn main() {
+ /// let mut core = Core::new().unwrap();
+ /// let client = IpfsClient::default(&core.handle());
+ /// let peer = "QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM";
+ /// let req = client.dht_findpeer(peer).collect();
+ /// # }
+ /// ```
+ ///
#[inline]
pub fn dht_findpeer(&self, peer: &str) -> AsyncStreamResponse<response::DhtFindPeerResponse> {
- self.request_stream(&request::DhtFindPeer { peer }, None)
+ self.request_stream_json(&request::DhtFindPeer { peer }, None)
}
/// Find peers in the DHT that can provide a specific value given a key.
///
+ /// ```no_run
+ /// # extern crate futures;
+ /// # extern crate ipfs_api;
+ /// # extern crate tokio_core;
+ /// #
+ /// use futures::stream::Stream;
+ /// use ipfs_api::IpfsClient;
+ /// use tokio_core::reactor::Core;
+ ///
+ /// # fn main() {
+ /// let mut core = Core::new().unwrap();
+ /// let client = IpfsClient::default(&core.handle());
+ /// let key = "QmXdNSQx7nbdRvkjGCEQgVjVtVwsHvV8NmV2a8xzQVwuFA";
+ /// let req = client.dht_findprovs(key).collect();
+ /// # }
+ /// ```
+ ///
#[inline]
pub fn dht_findprovs(&self, key: &str) -> AsyncStreamResponse<response::DhtFindProvsResponse> {
- self.request_stream(&request::DhtFindProvs { key }, None)
+ self.request_stream_json(&request::DhtFindProvs { key }, None)
}
/// Query the DHT for a given key.
///
+ /// ```no_run
+ /// # extern crate futures;
+ /// # extern crate ipfs_api;
+ /// # extern crate tokio_core;
+ /// #
+ /// use futures::stream::Stream;
+ /// use ipfs_api::IpfsClient;
+ /// use tokio_core::reactor::Core;
+ ///
+ /// # fn main() {
+ /// let mut core = Core::new(