diff options
author | Ferris Tseng <ferristseng@fastmail.fm> | 2017-11-03 00:01:21 -0400 |
---|---|---|
committer | Ferris Tseng <ferristseng@fastmail.fm> | 2017-11-03 00:01:21 -0400 |
commit | c28e62d54e1794e55688cb6ad81ea48b62e202d1 (patch) | |
tree | 99b02521c597cbad10dfaf32c54f5453d7353b21 | |
parent | f6b594b9ada9396cebdd3d8d4cb37c86d6198301 (diff) |
add new commands
-rw-r--r-- | ipfs-api/src/client.rs | 87 | ||||
-rw-r--r-- | ipfs-api/src/lib.rs | 3 | ||||
-rw-r--r-- | ipfs-api/src/read.rs | 29 | ||||
-rw-r--r-- | ipfs-api/src/request/id.rs | 23 | ||||
-rw-r--r-- | ipfs-api/src/request/key.rs | 62 | ||||
-rw-r--r-- | ipfs-api/src/request/log.rs | 99 | ||||
-rw-r--r-- | ipfs-api/src/request/mod.rs | 6 | ||||
-rw-r--r-- | ipfs-api/src/response/dht.rs | 3 | ||||
-rw-r--r-- | ipfs-api/src/response/id.rs | 2 | ||||
-rw-r--r-- | ipfs-api/src/response/key.rs | 4 | ||||
-rw-r--r-- | ipfs-api/src/response/log.rs | 4 |
11 files changed, 307 insertions, 15 deletions
diff --git a/ipfs-api/src/client.rs b/ipfs-api/src/client.rs index 6a22f07..9640a54 100644 --- a/ipfs-api/src/client.rs +++ b/ipfs-api/src/client.rs @@ -9,7 +9,7 @@ use futures::{stream, Stream}; use futures::future::{Future, IntoFuture}; use header::Trailer; -use read::{JsonLineDecoder, StreamReader}; +use read::{JsonLineDecoder, LineDecoder, StreamReader}; use request::{self, ApiRequest}; use response::{self, Error, ErrorKind}; use hyper::{self, Body, Chunk, Request, Response, Uri, Method, StatusCode}; @@ -18,7 +18,7 @@ use serde::{Deserialize, Serialize}; use serde_json; use std::io::Read; use tokio_core::reactor::Handle; -use tokio_io::codec::FramedRead; +use tokio_io::codec::{Decoder, FramedRead}; /// A future response returned by the reqwest HTTP client. @@ -116,9 +116,13 @@ impl IpfsClient { /// Processes a response that returns a stream of json deserializable /// results. /// - fn process_stream_response<Res>(res: Response) -> Box<Stream<Item = Res, Error = Error>> + fn process_stream_response<D, Res>( + res: Response, + decoder: D, + ) -> Box<Stream<Item = Res, Error = Error>> where - for<'de> Res: 'static + Deserialize<'de>, + D: 'static + Decoder<Item = Res, Error = Error>, + Res: 'static, { let err: Option<Error> = if let Some(trailer) = res.headers().get() { // Response has the Trailer header set, which is used @@ -132,10 +136,7 @@ impl IpfsClient { None }; - let stream = FramedRead::new( - StreamReader::new(res.body().from_err()), - JsonLineDecoder::new(), - ); + let stream = FramedRead::new(StreamReader::new(res.body().from_err()), decoder); if let Some(inner) = err { // If there was an error while streaming data back, read @@ -293,7 +294,9 @@ impl IpfsClient { .map(|req| self.client.request(req).from_err()) .into_future() .flatten() - .map(IpfsClient::process_stream_response) + .map(|res| { + IpfsClient::process_stream_response(res, JsonLineDecoder::new()) + }) .flatten_stream(); Box::new(res) @@ -454,6 +457,13 @@ impl IpfsClient { self.request_stream(&request::DhtGet { key }) } + /// Announce to the network that you are providing a given value. + /// + #[inline] + pub fn dht_provide(&self, key: &str) -> AsyncResponse<response::DhtProvideResponse> { + self.request(&request::DhtProvide { key }) + } + /// Write a key/value pair to the DHT. /// #[inline] @@ -606,6 +616,65 @@ impl IpfsClient { self.request_bytes(&request::Get { path }) } + /// Returns information about a peer. + /// + /// If `peer` is `None`, returns information about you. + /// + #[inline] + pub fn id(&self, peer: Option<&str>) -> AsyncResponse<response::IdResponse> { + self.request(&request::Id { peer }) + } + + /// Create a new keypair. + /// + #[inline] + pub fn key_gen( + &self, + name: &str, + kind: request::KeyType, + size: Option<i32>, + ) -> AsyncResponse<response::KeyGenResponse> { + self.request(&request::KeyGen { name, kind, size }) + } + + /// List all local keypairs. + /// + #[inline] + pub fn key_list(&self) -> AsyncResponse<response::KeyListResponse> { + self.request(&request::KeyList) + } + + /// Change the logging level for a logger. + /// + #[inline] + pub fn log_level( + &self, + logger: request::Logger, + level: request::LoggingLevel, + ) -> AsyncResponse<response::LogLevelResponse> { + self.request(&request::LogLevel { logger, level }) + } + + /// List all logging subsystems. + /// + #[inline] + pub fn log_ls(&self) -> AsyncResponse<response::LogLsResponse> { + self.request(&request::LogLs) + } + + /// Read the event log. + /// + pub fn log_tail(&self) -> AsyncStreamResponse<String> { + let res = self.build_base_request(&request::LogTail) + .map(|req| self.client.request(req).from_err()) + .into_future() + .flatten() + .map(|res| IpfsClient::process_stream_response(res, LineDecoder)) + .flatten_stream(); + + Box::new(res) + } + /// List the contents of an Ipfs multihash. /// #[inline] diff --git a/ipfs-api/src/lib.rs b/ipfs-api/src/lib.rs index 54b8106..ad8aee7 100644 --- a/ipfs-api/src/lib.rs +++ b/ipfs-api/src/lib.rs @@ -20,8 +20,9 @@ extern crate tokio_core; extern crate tokio_io; pub use client::IpfsClient; +pub use request::{KeyType, Logger, LoggingLevel}; -pub mod request; +mod request; pub mod response; mod client; mod header; diff --git a/ipfs-api/src/read.rs b/ipfs-api/src/read.rs index 0a009b5..9cea164 100644 --- a/ipfs-api/src/read.rs +++ b/ipfs-api/src/read.rs @@ -57,6 +57,35 @@ where } +/// A decoder that reads a line at a time. +/// +pub struct LineDecoder; + +impl Decoder for LineDecoder { + type Item = String; + + type Error = Error; + + /// Attempts to find a new line character, and returns the entire line if + /// it finds one. + /// + fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> { + let nl_index = src.iter().position(|b| *b == b'\n'); + + if let Some(pos) = nl_index { + let slice = src.split_to(pos + 1); + + Ok(Some( + String::from_utf8_lossy(&slice[..slice.len() - 1]) + .into_owned(), + )) + } else { + Ok(None) + } + } +} + + /// The state of a stream returning Chunks. /// enum ReadState { diff --git a/ipfs-api/src/request/id.rs b/ipfs-api/src/request/id.rs new file mode 100644 index 0000000..a97aa67 --- /dev/null +++ b/ipfs-api/src/request/id.rs @@ -0,0 +1,23 @@ +// Copyright 2017 rust-ipfs-api Developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. +// + +use request::ApiRequest; + + +#[derive(Serialize)] +pub struct Id<'a> { + #[serde(rename = "arg")] + pub peer: Option<&'a str>, +} + +impl<'a> ApiRequest for Id<'a> { + #[inline] + fn path() -> &'static str { + "/id" + } +} diff --git a/ipfs-api/src/request/key.rs b/ipfs-api/src/request/key.rs new file mode 100644 index 0000000..e3c72ce --- /dev/null +++ b/ipfs-api/src/request/key.rs @@ -0,0 +1,62 @@ +// Copyright 2017 rust-ipfs-api Developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. +// + +use request::ApiRequest; +use serde::ser::{Serialize, Serializer}; + + +#[derive(Copy, Clone)] +pub enum KeyType { + Rsa, + Ed25519, +} + +impl Serialize for KeyType { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + let s = match self { + &KeyType::Rsa => "rsa", + &KeyType::Ed25519 => "ed25519", + }; + + serializer.serialize_str(s) + } +} + + +#[derive(Serialize)] +pub struct KeyGen<'a> { + #[serde(rename = "arg")] + pub name: &'a str, + + #[serde(rename = "type")] + pub kind: KeyType, + + pub size: Option<i32>, +} + +impl<'a> ApiRequest for KeyGen<'a> { + #[inline] + fn path() -> &'static str { + "/key/gen" + } +} + + +pub struct KeyList; + +impl_skip_serialize!(KeyList); + +impl ApiRequest for KeyList { + #[inline] + fn path() -> &'static str { + "/key/list" + } +} diff --git a/ipfs-api/src/request/log.rs b/ipfs-api/src/request/log.rs new file mode 100644 index 0000000..7a48e5f --- /dev/null +++ b/ipfs-api/src/request/log.rs @@ -0,0 +1,99 @@ +// Copyright 2017 rust-ipfs-api Developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. +// + +use request::ApiRequest; +use serde::ser::{Serialize, Serializer}; +use std::borrow::Cow; + + +#[derive(Copy, Clone)] +pub enum LoggingLevel { + Debug, + Info, + Warning, + Error, + Critical, +} + +impl Serialize for LoggingLevel { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + let s = match self { + &LoggingLevel::Debug => "debug", + &LoggingLevel::Info => "info", + &LoggingLevel::Warning => "warning", + &LoggingLevel::Error => "error", + &LoggingLevel::Critical => "critical", + }; + + serializer.serialize_str(s) + } +} + + +pub enum Logger<'a> { + All, + Specific(Cow<'a, str>), +} + +impl<'a> Serialize for Logger<'a> { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + let s = match self { + &Logger::All => "*", + &Logger::Specific(ref logger) => logger.as_ref(), + }; + + serializer.serialize_str(s) + } +} + + +#[derive(Serialize)] +pub struct LogLevel<'a> { + #[serde(rename = "arg")] + pub logger: Logger<'a>, + + #[serde(rename = "arg")] + pub level: LoggingLevel, +} + +impl<'a> ApiRequest for LogLevel<'a> { + #[inline] + fn path() -> &'static str { + "/log/level" + } +} + + +pub struct LogLs; + +impl_skip_serialize!(LogLs); + +impl ApiRequest for LogLs { + #[inline] + fn path() -> &'static str { + "/log/ls" + } +} + + +pub struct LogTail; + +impl_skip_serialize!(LogTail); + +impl ApiRequest for LogTail { + #[inline] + fn path() -> &'static str { + "/log/tail" + } +} diff --git a/ipfs-api/src/request/mod.rs b/ipfs-api/src/request/mod.rs index 438c6c2..81f1dc1 100644 --- a/ipfs-api/src/request/mod.rs +++ b/ipfs-api/src/request/mod.rs @@ -21,7 +21,10 @@ pub use self::file::*; pub use self::files::*; pub use self::filestore::*; pub use self::get::*; +pub use self::log::*; pub use self::ls::*; +pub use self::id::*; +pub use self::key::*; pub use self::object::*; pub use self::pin::*; pub use self::ping::*; @@ -81,7 +84,10 @@ mod file; mod files; mod filestore; mod get; +mod log; mod ls; +mod id; +mod key; mod object; mod pin; mod ping; diff --git a/ipfs-api/src/response/dht.rs b/ipfs-api/src/response/dht.rs index c0b6d36..b8493e7 100644 --- a/ipfs-api/src/response/dht.rs +++ b/ipfs-api/src/response/dht.rs @@ -35,12 +35,15 @@ pub struct DhtMessage { pub extra: String, } + pub type DhtFindPeerResponse = DhtMessage; pub type DhtFindProvsResponse = DhtMessage; pub type DhtGetResponse = DhtMessage; +pub type DhtProvideResponse = DhtMessage; + pub type DhtPutResponse = DhtMessage; pub type DhtQueryResponse = DhtMessage; diff --git a/ipfs-api/src/response/id.rs b/ipfs-api/src/response/id.rs index 4271140..72a0569 100644 --- a/ipfs-api/src/response/id.rs +++ b/ipfs-api/src/response/id.rs @@ -9,7 +9,7 @@ use response::serde; -#[derive(Deserialize)] +#[derive(Debug, Deserialize)] #[serde(rename_all = "PascalCase")] pub struct IdResponse { #[serde(rename = "ID")] diff --git a/ipfs-api/src/response/key.rs b/ipfs-api/src/response/key.rs index 7059bc0..2eb7de7 100644 --- a/ipfs-api/src/response/key.rs +++ b/ipfs-api/src/response/key.rs @@ -9,7 +9,7 @@ use response::serde; -#[derive(Deserialize)] +#[derive(Debug, Deserialize)] #[serde(rename_all = "PascalCase")] pub struct KeyGenResponse { pub name: String, @@ -17,7 +17,7 @@ pub struct KeyGenResponse { } -#[derive(Deserialize)] +#[derive(Debug, Deserialize)] #[serde(rename_all = "PascalCase")] pub struct KeyListResponse { #[serde(deserialize_with = "serde::deserialize_vec")] diff --git a/ipfs-api/src/response/log.rs b/ipfs-api/src/response/log.rs index fce6fcf..643d341 100644 --- a/ipfs-api/src/response/log.rs +++ b/ipfs-api/src/response/log.rs @@ -9,14 +9,14 @@ use response::serde; -#[derive(Deserialize)] +#[derive(Debug, Deserialize)] #[serde(rename_all = "PascalCase")] pub struct LogLevelResponse { pub message: String, } -#[derive(Deserialize)] +#[derive(Debug, Deserialize)] #[serde(rename_all = "PascalCase")] pub struct LogLsResponse { #[serde(deserialize_with = "serde::deserialize_vec")] |