summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFerris Tseng <ferristseng@fastmail.fm>2017-10-08 17:31:44 -0400
committerFerris Tseng <ferristseng@fastmail.fm>2017-10-08 17:31:44 -0400
commit731cb96c9a691fe0165b396bdd8dd8dd6a09d8f1 (patch)
treea1d5deda16ae6e367296c830871e96635940f76a
parent89c7155c95a756e8ed824555ad44fb03d3c02020 (diff)
implement simple client
-rw-r--r--Cargo.toml2
-rw-r--r--src/client.rs55
-rw-r--r--src/lib.rs6
-rw-r--r--src/response/error.rs55
-rw-r--r--src/response/ls.rs2
-rw-r--r--src/response/mod.rs4
-rw-r--r--src/response/version.rs8
7 files changed, 124 insertions, 8 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 3020f9e..e25da0c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -5,7 +5,9 @@ authors = ["Ferris Tseng <ferristseng@fastmail.fm>"]
[dependencies]
base58 = "0.1"
+futures = "0.1"
hyper = "0.11"
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
+tokio-core = "0.1"
diff --git a/src/client.rs b/src/client.rs
new file mode 100644
index 0000000..5328a2d
--- /dev/null
+++ b/src/client.rs
@@ -0,0 +1,55 @@
+use futures::Stream;
+use futures::future::Future;
+use hyper::Uri;
+use hyper::client::{Client, HttpConnector};
+use hyper::error::UriError;
+use response::{self, Error};
+use serde_json;
+use tokio_core::reactor::Handle;
+
+
+pub type AsyncResponse<T> = Box<Future<Item = T, Error = Error>>;
+
+
+pub struct IpfsClient {
+ base: Uri,
+ client: Client<HttpConnector>,
+}
+
+impl IpfsClient {
+ /// Creates a new `IpfsClient`.
+ ///
+ #[inline]
+ pub fn new(handle: &Handle, host: &str, port: u16) -> Result<IpfsClient, UriError> {
+ let base_path = IpfsClient::build_base_path(host, port)?;
+
+ Ok(IpfsClient {
+ base: base_path,
+ client: Client::new(handle),
+ })
+ }
+
+ /// Builds the base uri path for the Ipfs API.
+ ///
+ fn build_base_path(host: &str, port: u16) -> Result<Uri, UriError> {
+ format!("http://{}:{}/api/v0", host, port).parse()
+ }
+}
+
+impl IpfsClient {
+ /// Returns information about the Ipfs server version.
+ ///
+ pub fn version(&self) -> AsyncResponse<response::VersionResponse> {
+ let uri = format!("{}/version", self.base).parse().unwrap();
+
+ Box::new(
+ self.client
+ .get(uri)
+ .and_then(|res| res.body().concat2())
+ .from_err()
+ .and_then(move |body| {
+ serde_json::from_slice(&body).map_err(From::from)
+ }),
+ )
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 892e7c2..999a596 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,9 +1,15 @@
extern crate base58;
+extern crate futures;
extern crate hyper;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
+extern crate tokio_core;
+
+
+pub use client::IpfsClient;
pub mod response;
+mod client;
diff --git a/src/response/error.rs b/src/response/error.rs
index 252adef..3eb8f1b 100644
--- a/src/response/error.rs
+++ b/src/response/error.rs
@@ -1,6 +1,55 @@
-#[derive(Deserialize)]
+use hyper;
+use serde_json;
+use std::fmt::{self, Display, Formatter};
+
+
+#[derive(Debug)]
+pub enum Error {
+ Http(hyper::error::Error),
+ Parse(serde_json::Error),
+ Api(ApiError),
+ Uncategorized(String),
+}
+
+impl From<hyper::error::Error> for Error {
+ fn from(error: hyper::error::Error) -> Self {
+ Error::Http(error)
+ }
+}
+
+impl From<serde_json::Error> for Error {
+ fn from(error: serde_json::Error) -> Self {
+ Error::Parse(error)
+ }
+}
+
+impl From<ApiError> for Error {
+ fn from(error: ApiError) -> Self {
+ Error::Api(error)
+ }
+}
+
+impl Display for Error {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(f, "{:?}", self)
+ }
+}
+
+impl ::std::error::Error for Error {
+ fn description(&self) -> &str {
+ match *self {
+ Error::Http(_) => "an http error occured",
+ Error::Parse(_) => "an error occursed while parsing the api response",
+ Error::Api(_) => "an api error occured",
+ Error::Uncategorized(_) => "an unknown error occured",
+ }
+ }
+}
+
+
+#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
-pub struct Error {
+pub struct ApiError {
pub message: String,
- pub code: u8
+ pub code: u8,
}
diff --git a/src/response/ls.rs b/src/response/ls.rs
index 29bc42e..de8efb9 100644
--- a/src/response/ls.rs
+++ b/src/response/ls.rs
@@ -5,7 +5,7 @@ use response::{serde, IpfsFile};
#[serde(rename_all = "PascalCase")]
pub struct LsResponse {
#[serde(deserialize_with = "serde::deserialize_vec")]
- pub objects: Vec<IpfsFile>
+ pub objects: Vec<IpfsFile>,
}
diff --git a/src/response/mod.rs b/src/response/mod.rs
index 49056ab..317f20f 100644
--- a/src/response/mod.rs
+++ b/src/response/mod.rs
@@ -16,6 +16,7 @@ pub use self::filestore::*;
pub use self::id::*;
pub use self::key::*;
pub use self::log::*;
+pub use self::ls::*;
pub use self::mount::*;
pub use self::name::*;
pub use self::object::*;
@@ -28,6 +29,7 @@ pub use self::resolve::*;
pub use self::stats::*;
pub use self::swarm::*;
pub use self::tar::*;
+pub use self::version::*;
/// Create a test to deserialize a file to the given instance.
@@ -67,6 +69,7 @@ mod get;
mod id;
mod key;
mod log;
+mod ls;
mod mount;
mod name;
mod object;
@@ -80,6 +83,7 @@ mod serde;
mod stats;
mod swarm;
mod tar;
+mod version;
#[derive(Deserialize)]
diff --git a/src/response/version.rs b/src/response/version.rs
index 05178d5..8c91ce8 100644
--- a/src/response/version.rs
+++ b/src/response/version.rs
@@ -1,15 +1,15 @@
-#[derive(Deserialize)]
+#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
-pub struct Version {
+pub struct VersionResponse {
pub version: String,
pub commit: String,
pub repo: String,
pub system: String,
- pub golang: String
+ pub golang: String,
}
#[cfg(test)]
mod tests {
- deserialize_test!(v0_version_0, Version);
+ deserialize_test!(v0_version_0, VersionResponse);
}