summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock2
-rw-r--r--README.md4
-rw-r--r--ipfs-api/Cargo.toml2
-rw-r--r--ipfs-api/examples/mfs.rs12
-rw-r--r--ipfs-api/src/client/internal.rs93
-rw-r--r--ipfs-api/src/request/files.rs63
-rw-r--r--ipfs-api/src/response/files.rs7
7 files changed, 151 insertions, 32 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 22ab27f..2f3af8c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -956,7 +956,7 @@ dependencies = [
[[package]]
name = "ipfs-api"
-version = "0.7.2"
+version = "0.8.0"
dependencies = [
"actix-http 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-multipart-rfc7578 0.3.0-rc (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/README.md b/README.md
index 254d89f..7427c36 100644
--- a/README.md
+++ b/README.md
@@ -10,14 +10,14 @@ Rust library for connecting to the IPFS HTTP API using tokio.
```toml
[dependencies]
-ipfs-api = "0.7.2"
+ipfs-api = "0.8"
```
You can use `actix-web` as a backend instead of `hyper`.
```toml
[dependencies]
-ipfs-api = { version = "0.7.2", features = ["actix"], default-features = false }
+ipfs-api = { version = "0.8", features = ["actix"], default-features = false }
```
### Examples
diff --git a/ipfs-api/Cargo.toml b/ipfs-api/Cargo.toml
index 9f2ca23..76deb6e 100644
--- a/ipfs-api/Cargo.toml
+++ b/ipfs-api/Cargo.toml
@@ -7,7 +7,7 @@ documentation = "https://docs.rs/ipfs-api"
repository = "https://github.com/ferristseng/rust-ipfs-api"
keywords = ["ipfs"]
categories = ["filesystem", "web-programming"]
-version = "0.7.2"
+version = "0.8.0"
readme = "../README.md"
license = "MIT OR Apache-2.0"
diff --git a/ipfs-api/examples/mfs.rs b/ipfs-api/examples/mfs.rs
index 3d6419c..2b20111 100644
--- a/ipfs-api/examples/mfs.rs
+++ b/ipfs-api/examples/mfs.rs
@@ -31,7 +31,7 @@ async fn main() {
eprintln!("making /test...");
eprintln!();
- if let Err(e) = client.files_mkdir("/test", false).await {
+ if let Err(e) = client.files_mkdir("/test", false, 0, None, true).await {
eprintln!("error making /test: {}", e);
return;
}
@@ -39,7 +39,7 @@ async fn main() {
eprintln!("making dirs /test/does/not/exist/yet...");
eprintln!();
- if let Err(e) = client.files_mkdir("/test/does/not/exist/yet", true).await {
+ if let Err(e) = client.files_mkdir("/test/does/not/exist/yet", true, 0, None, true).await {
eprintln!("error making /test/does/not/exist/yet: {}", e);
return;
}
@@ -47,7 +47,7 @@ async fn main() {
eprintln!("getting status of /test/does...");
eprintln!();
- match client.files_stat("/test/does").await {
+ match client.files_stat("/test/does", false).await {
Ok(stat) => print_stat(stat),
Err(e) => {
eprintln!("error getting status of /test/does: {}", e);
@@ -60,7 +60,7 @@ async fn main() {
let src = File::open(file!()).expect("could not read source file");
- if let Err(e) = client.files_write("/test/mfs.rs", true, true, src).await {
+ if let Err(e) = client.files_write("/test/mfs.rs", true, true, false, 0, None, false, 0, None, true, src).await {
eprintln!("error writing source file /test/mfs.rs: {}", e);
return;
}
@@ -68,7 +68,7 @@ async fn main() {
eprintln!("getting status of /test/mfs.rs...");
eprintln!();
- match client.files_stat("/test/mfs.rs").await {
+ match client.files_stat("/test/mfs.rs", false).await {
Ok(stat) => print_stat(stat),
Err(e) => {
eprintln!("error getting status of /test/mfs.rs: {}", e);
@@ -79,7 +79,7 @@ async fn main() {
eprintln!("removing /test...");
eprintln!();
- if let Err(e) = client.files_rm("/test", true).await {
+ if let Err(e) = client.files_rm("/test", true, true).await {
eprintln!("error removing /test: {}", e);
}
diff --git a/ipfs-api/src/client/internal.rs b/ipfs-api/src/client/internal.rs
index 475ec17..885f6a4 100644
--- a/ipfs-api/src/client/internal.rs
+++ b/ipfs-api/src/client/internal.rs
@@ -1113,7 +1113,7 @@ impl IpfsClient {
/// use ipfs_api::IpfsClient;
///
/// let client = IpfsClient::default();
- /// let res = client.files_cp("/path/to/file", "/dest");
+ /// let res = client.files_cp("/path/to/file", "/dest", true);
/// ```
///
#[inline]
@@ -1121,8 +1121,9 @@ impl IpfsClient {
&self,
path: &str,
dest: &str,
+ flush: bool,
) -> Result<response::FilesCpResponse, Error> {
- self.request_empty(request::FilesCp { path, dest }, None)
+ self.request_empty(request::FilesCp { path, dest, flush }, None)
.await
}
@@ -1144,19 +1145,19 @@ impl IpfsClient {
self.request_empty(request::FilesFlush { path }, None).await
}
- /// List directories in MFS.
+ /// List directories in MFS. Always passes `-U`.
///
/// ```no_run
/// use ipfs_api::IpfsClient;
///
/// let client = IpfsClient::default();
- /// let res = client.files_ls(None);
- /// let res = client.files_ls(Some("/tmp"));
+ /// let res = client.files_ls(None, false);
+ /// let res = client.files_ls(Some("/tmp"), true);
/// ```
///
#[inline]
- pub async fn files_ls(&self, path: Option<&str>) -> Result<response::FilesLsResponse, Error> {
- self.request(request::FilesLs { path }, None).await
+ pub async fn files_ls(&self, path: Option<&str>, long: bool) -> Result<response::FilesLsResponse, Error> {
+ self.request(request::FilesLs { path, long, unsorted: true }, None).await
}
/// Make directories in MFS.
@@ -1165,8 +1166,8 @@ impl IpfsClient {
/// use ipfs_api::IpfsClient;
///
/// let client = IpfsClient::default();
- /// let res = client.files_mkdir("/test", false);
- /// let res = client.files_mkdir("/test/nested/dir", true);
+ /// let res = client.files_mkdir("/test", false, 0, None, true);
+ /// let res = client.files_mkdir("/test/nested/dir", true, 0, None, true);
/// ```
///
#[inline]
@@ -1174,8 +1175,11 @@ impl IpfsClient {
&self,
path: &str,
parents: bool,
+ cid_version: i32,
+ hash: Option<&str>,
+ flush: bool,
) -> Result<response::FilesMkdirResponse, Error> {
- self.request_empty(request::FilesMkdir { path, parents }, None)
+ self.request_empty(request::FilesMkdir { path, parents, cid_version, hash, flush }, None)
.await
}
@@ -1185,7 +1189,7 @@ impl IpfsClient {
/// use ipfs_api::IpfsClient;
///
/// let client = IpfsClient::default();
- /// let res = client.files_mv("/test/tmp.json", "/test/file.json");
+ /// let res = client.files_mv("/test/tmp.json", "/test/file.json", true);
/// ```
///
#[inline]
@@ -1193,8 +1197,9 @@ impl IpfsClient {
&self,
path: &str,
dest: &str,
+ flush: bool,
) -> Result<response::FilesMvResponse, Error> {
- self.request_empty(request::FilesMv { path, dest }, None)
+ self.request_empty(request::FilesMv { path, dest, flush }, None)
.await
}
@@ -1204,13 +1209,15 @@ impl IpfsClient {
/// use ipfs_api::IpfsClient;
///
/// let client = IpfsClient::default();
- /// let res = client.files_read("/test/file.json");
+ /// let res = client.files_read("/test/file.json", 0, None);
/// ```
///
+ /// Not specifying a byte `count` reads to the end of the file.
+ ///
#[inline]
- pub fn files_read(&self, path: &str) -> impl Stream<Item = Result<Bytes, Error>> {
+ pub fn files_read(&self, path: &str, offset: i64, count: Option<i64>) -> impl Stream<Item = Result<Bytes, Error>> {
impl_stream_api_response! {
- (self, request::FilesRead { path }, None) => request_stream_bytes
+ (self, request::FilesRead { path, offset, count }, None) => request_stream_bytes
}
}
@@ -1220,8 +1227,8 @@ impl IpfsClient {
/// use ipfs_api::IpfsClient;
///
/// let client = IpfsClient::default();
- /// let res = client.files_rm("/test/dir", true);
- /// let res = client.files_rm("/test/file.json", false);
+ /// let res = client.files_rm("/test/dir", true, true);
+ /// let res = client.files_rm("/test/file.json", false, true);
/// ```
///
#[inline]
@@ -1229,8 +1236,9 @@ impl IpfsClient {
&self,
path: &str,
recursive: bool,
+ flush: bool,
) -> Result<response::FilesRmResponse, Error> {
- self.request_empty(request::FilesRm { path, recursive }, None)
+ self.request_empty(request::FilesRm { path, recursive, flush }, None)
.await
}
@@ -1240,12 +1248,12 @@ impl IpfsClient {
/// use ipfs_api::IpfsClient;
///
/// let client = IpfsClient::default();
- /// let res = client.files_stat("/test/file.json");
+ /// let res = client.files_stat("/test/file.json", false);
/// ```
///
#[inline]
- pub async fn files_stat(&self, path: &str) -> Result<response::FilesStatResponse, Error> {
- self.request(request::FilesStat { path }, None).await
+ pub async fn files_stat(&self, path: &str, with_local: bool) -> Result<response::FilesStatResponse, Error> {
+ self.request(request::FilesStat { path, with_local }, None).await
}
/// Write to a mutable file in the filesystem.
@@ -1256,15 +1264,24 @@ impl IpfsClient {
///
/// let client = IpfsClient::default();
/// let file = File::open("test.json").unwrap();
- /// let res = client.files_write("/test/file.json", true, true, file);
+ /// let res = client.files_write("/test/file.json", true, true, true, 0, None, false, 0, None, true, file);
/// ```
///
+ /// Not specifying a byte `count` writes the entire input.
+ ///
#[inline]
pub async fn files_write<R>(
&self,
path: &str,
create: bool,
truncate: bool,
+ parents: bool,
+ offset: i64,
+ count: Option<i64>,
+ raw_leaves: bool,
+ cid_version: i32,
+ hash: Option<&str>,
+ flush: bool,
data: R,
) -> Result<response::FilesWriteResponse, Error>
where
@@ -1279,12 +1296,44 @@ impl IpfsClient {
path,
create,
truncate,
+ parents,
+ offset,
+ count,
+ raw_leaves,
+ cid_version,
+ hash,
+ flush,
},
Some(form),
)
.await
}
+ /// Change the cid version or hash function of the root node of a given path.
+ ///
+ /// ```no_run
+ /// use ipfs_api::IpfsClient;
+ /// use std::fs::File;
+ ///
+ /// let client = IpfsClient::default();
+ /// let res = client.files_chcid("/test/", 1, Some("sha3-512"), true);
+ /// ```
+ ///
+ /// Not specifying a byte `count` writes the entire input.
+ ///
+ #[inline]
+ pub async fn files_chcid(
+ &self,
+ path: &str,
+ cid_version: i32,
+ hash: Option<&str>,
+ flush: bool,
+ ) -> Result<response::FilesChcidResponse, Error>
+ {
+ self.request_empty(request::FilesChcid { path, cid_version, hash, flush }, None)
+ .await
+ }
+
/// List blocks that are both in the filestore and standard block storage.
///
/// ```no_run
diff --git a/ipfs-api/src/request/files.rs b/ipfs-api/src/request/files.rs
index 3ec4186..109f107 100644
--- a/ipfs-api/src/request/files.rs
+++ b/ipfs-api/src/request/files.rs
@@ -16,6 +16,8 @@ pub struct FilesCp<'a> {
#[serde(rename = "arg")]
pub dest: &'a str,
+
+ pub flush: bool,
}
impl<'a> ApiRequest for FilesCp<'a> {
@@ -36,6 +38,11 @@ impl<'a> ApiRequest for FilesFlush<'a> {
pub struct FilesLs<'a> {
#[serde(rename = "arg")]
pub path: Option<&'a str>,
+
+ pub long: bool,
+
+ #[serde(rename = "U")]
+ pub unsorted: bool,
}
impl<'a> ApiRequest for FilesLs<'a> {
@@ -48,6 +55,14 @@ pub struct FilesMkdir<'a> {
pub path: &'a str,
pub parents: bool,
+
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub hash: Option<&'a str>,
+
+ #[serde(rename = "cid-version")]
+ pub cid_version: i32,
+
+ pub flush: bool,
}
impl<'a> ApiRequest for FilesMkdir<'a> {
@@ -61,6 +76,8 @@ pub struct FilesMv<'a> {
#[serde(rename = "arg")]
pub dest: &'a str,
+
+ pub flush: bool,
}
impl<'a> ApiRequest for FilesMv<'a> {
@@ -71,6 +88,11 @@ impl<'a> ApiRequest for FilesMv<'a> {
pub struct FilesRead<'a> {
#[serde(rename = "arg")]
pub path: &'a str,
+
+ pub offset: i64,
+
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub count: Option<i64>,
}
impl<'a> ApiRequest for FilesRead<'a> {
@@ -83,6 +105,8 @@ pub struct FilesRm<'a> {
pub path: &'a str,
pub recursive: bool,
+
+ pub flush: bool,
}
impl<'a> ApiRequest for FilesRm<'a> {
@@ -93,6 +117,9 @@ impl<'a> ApiRequest for FilesRm<'a> {
pub struct FilesStat<'a> {
#[serde(rename = "arg")]
pub path: &'a str,
+
+ #[serde(rename = "with-local")]
+ pub with_local: bool,
}
impl<'a> ApiRequest for FilesStat<'a> {
@@ -107,8 +134,44 @@ pub struct FilesWrite<'a> {
pub create: bool,
pub truncate: bool,
+
+ pub parents: bool,
+
+ pub offset: i64,
+
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub count: Option<i64>,
+
+ #[serde(rename = "raw-leaves")]
+ pub raw_leaves: bool,
+
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub hash: Option<&'a str>,
+
+ #[serde(rename = "cid-version")]
+ pub cid_version: i32,
+
+ pub flush: bool,
}
impl<'a> ApiRequest for FilesWrite<'a> {
const PATH: &'static str = "/files/write";
}
+
+#[derive(Serialize)]
+pub struct FilesChcid<'a> {
+ #[serde(rename = "arg")]
+ pub path: &'a str,
+
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub hash: Option<&'a str>,
+
+ #[serde(rename = "cid-version")]
+ pub cid_version: i32,
+
+ pub flush: bool,
+}
+
+impl<'a> ApiRequest for FilesChcid<'a> {
+ const PATH: &'static str = "/files/chcid";
+}
diff --git a/ipfs-api/src/response/files.rs b/ipfs-api/src/response/files.rs
index 069ba32..f27be1f 100644
--- a/ipfs-api/src/response/files.rs
+++ b/ipfs-api/src/response/files.rs
@@ -50,10 +50,17 @@ pub struct FilesStatResponse {
#[serde(rename = "Type")]
pub typ: String,
+
+ #[serde(default)]
+ pub size_local: Option<u64>,
+ #[serde(default)]
+ pub local: Option<bool>,
}
pub type FilesWriteResponse = ();
+pub type FilesChcidResponse = ();
+
#[cfg(test)]
mod tests {
deserialize_test!(v0_files_ls_0, FilesLsResponse);