From 208a23371318ef9f61a27301093ea6667996102e Mon Sep 17 00:00:00 2001 From: Julius Michaelis Date: Thu, 9 Jul 2020 15:36:29 +0900 Subject: 0.7.2 -> 0.8.0 (about to commit breaking change) --- Cargo.lock | 2 +- README.md | 4 ++-- ipfs-api/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b7aa567..b4eb92b 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 77ff907..b216fae 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" -- cgit v1.2.3 From 0bb7f70f91c422705804ba1fd14411b8c07e6136 Mon Sep 17 00:00:00 2001 From: Julius Michaelis Date: Thu, 9 Jul 2020 15:19:58 +0900 Subject: ipfs files read/write: add offset, count, parents --- ipfs-api/examples/mfs.rs | 2 +- ipfs-api/src/client/internal.rs | 18 ++++++++++++++---- ipfs-api/src/request/files.rs | 12 ++++++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/ipfs-api/examples/mfs.rs b/ipfs-api/examples/mfs.rs index 3d6419c..05851d9 100644 --- a/ipfs-api/examples/mfs.rs +++ b/ipfs-api/examples/mfs.rs @@ -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, src).await { eprintln!("error writing source file /test/mfs.rs: {}", e); return; } diff --git a/ipfs-api/src/client/internal.rs b/ipfs-api/src/client/internal.rs index 2c0d2af..ef4e9f2 100644 --- a/ipfs-api/src/client/internal.rs +++ b/ipfs-api/src/client/internal.rs @@ -1166,13 +1166,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> { + pub fn files_read(&self, path: &str, offset: i64, count: Option) -> impl Stream> { impl_stream_api_response! { - (self, request::FilesRead { path }, None) => request_stream_bytes + (self, request::FilesRead { path, offset, count }, None) => request_stream_bytes } } @@ -1218,15 +1220,20 @@ 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, file); /// ``` /// + /// Not specifying a byte `count` writes the entire input. + /// #[inline] pub async fn files_write( &self, path: &str, create: bool, truncate: bool, + parents: bool, + offset: i64, + count: Option, data: R, ) -> Result where @@ -1241,6 +1248,9 @@ impl IpfsClient { path, create, truncate, + parents, + offset, + count, }, Some(form), ) diff --git a/ipfs-api/src/request/files.rs b/ipfs-api/src/request/files.rs index 3ec4186..564bd6c 100644 --- a/ipfs-api/src/request/files.rs +++ b/ipfs-api/src/request/files.rs @@ -71,6 +71,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, } impl<'a> ApiRequest for FilesRead<'a> { @@ -107,6 +112,13 @@ 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, } impl<'a> ApiRequest for FilesWrite<'a> { -- cgit v1.2.3 From 27069656be40081303b7e3888b37b5c23231c5df Mon Sep 17 00:00:00 2001 From: Julius Michaelis Date: Thu, 9 Jul 2020 17:33:12 +0900 Subject: add ipfs files chcid --- ipfs-api/src/client/internal.rs | 24 ++++++++++++++++++++++++ ipfs-api/src/request/files.rs | 16 ++++++++++++++++ ipfs-api/src/response/files.rs | 2 ++ 3 files changed, 42 insertions(+) diff --git a/ipfs-api/src/client/internal.rs b/ipfs-api/src/client/internal.rs index ef4e9f2..6c646cc 100644 --- a/ipfs-api/src/client/internal.rs +++ b/ipfs-api/src/client/internal.rs @@ -1257,6 +1257,30 @@ impl IpfsClient { .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")); + /// ``` + /// + /// Not specifying a byte `count` writes the entire input. + /// + #[inline] + pub async fn files_chcid( + &self, + path: &str, + cid_version: i32, + hash: Option<&str>, + ) -> Result + { + self.request_empty(request::FilesChcid { path, cid_version, hash }, 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 564bd6c..6525a11 100644 --- a/ipfs-api/src/request/files.rs +++ b/ipfs-api/src/request/files.rs @@ -124,3 +124,19 @@ pub struct FilesWrite<'a> { 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, +} + +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..76dc4a1 100644 --- a/ipfs-api/src/response/files.rs +++ b/ipfs-api/src/response/files.rs @@ -54,6 +54,8 @@ pub struct FilesStatResponse { pub type FilesWriteResponse = (); +pub type FilesChcidResponse = (); + #[cfg(test)] mod tests { deserialize_test!(v0_files_ls_0, FilesLsResponse); -- cgit v1.2.3 From 106ae9287733bab4e6d5430a55f02fcf8447280e Mon Sep 17 00:00:00 2001 From: Julius Michaelis Date: Thu, 9 Jul 2020 17:58:44 +0900 Subject: add ipfs files write --raw-leaves --- ipfs-api/examples/mfs.rs | 2 +- ipfs-api/src/client/internal.rs | 4 +++- ipfs-api/src/request/files.rs | 3 +++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ipfs-api/examples/mfs.rs b/ipfs-api/examples/mfs.rs index 05851d9..dab272b 100644 --- a/ipfs-api/examples/mfs.rs +++ b/ipfs-api/examples/mfs.rs @@ -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, false, 0, None, src).await { + if let Err(e) = client.files_write("/test/mfs.rs", true, true, false, 0, None, false, src).await { eprintln!("error writing source file /test/mfs.rs: {}", e); return; } diff --git a/ipfs-api/src/client/internal.rs b/ipfs-api/src/client/internal.rs index 6c646cc..c28e251 100644 --- a/ipfs-api/src/client/internal.rs +++ b/ipfs-api/src/client/internal.rs @@ -1220,7 +1220,7 @@ impl IpfsClient { /// /// let client = IpfsClient::default(); /// let file = File::open("test.json").unwrap(); - /// let res = client.files_write("/test/file.json", true, true, true, 0, None, file); + /// let res = client.files_write("/test/file.json", true, true, true, 0, None, false, file); /// ``` /// /// Not specifying a byte `count` writes the entire input. @@ -1234,6 +1234,7 @@ impl IpfsClient { parents: bool, offset: i64, count: Option, + raw_leaves: bool, data: R, ) -> Result where @@ -1251,6 +1252,7 @@ impl IpfsClient { parents, offset, count, + raw_leaves, }, Some(form), ) diff --git a/ipfs-api/src/request/files.rs b/ipfs-api/src/request/files.rs index 6525a11..bcf17cc 100644 --- a/ipfs-api/src/request/files.rs +++ b/ipfs-api/src/request/files.rs @@ -119,6 +119,9 @@ pub struct FilesWrite<'a> { #[serde(skip_serializing_if = "Option::is_none")] pub count: Option, + + #[serde(rename = "raw-leaves")] + pub raw_leaves: bool, } impl<'a> ApiRequest for FilesWrite<'a> { -- cgit v1.2.3 From a162e2cbc3dd0898211056154af57e6ec58d7808 Mon Sep 17 00:00:00 2001 From: Julius Michaelis Date: Thu, 9 Jul 2020 17:55:15 +0900 Subject: ipfs files: cid-version, hash, flush --- ipfs-api/examples/mfs.rs | 8 ++++---- ipfs-api/src/client/internal.rs | 39 ++++++++++++++++++++++++++------------- ipfs-api/src/request/files.rs | 24 ++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 17 deletions(-) diff --git a/ipfs-api/examples/mfs.rs b/ipfs-api/examples/mfs.rs index dab272b..b53935c 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; } @@ -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, false, 0, None, false, 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; } @@ -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 c28e251..f317fe8 100644 --- a/ipfs-api/src/client/internal.rs +++ b/ipfs-api/src/client/internal.rs @@ -1075,7 +1075,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] @@ -1083,8 +1083,9 @@ impl IpfsClient { &self, path: &str, dest: &str, + flush: bool, ) -> Result { - self.request_empty(request::FilesCp { path, dest }, None) + self.request_empty(request::FilesCp { path, dest, flush }, None) .await } @@ -1127,8 +1128,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] @@ -1136,8 +1137,11 @@ impl IpfsClient { &self, path: &str, parents: bool, + cid_version: i32, + hash: Option<&str>, + flush: bool, ) -> Result { - self.request_empty(request::FilesMkdir { path, parents }, None) + self.request_empty(request::FilesMkdir { path, parents, cid_version, hash, flush }, None) .await } @@ -1147,7 +1151,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] @@ -1155,8 +1159,9 @@ impl IpfsClient { &self, path: &str, dest: &str, + flush: bool, ) -> Result { - self.request_empty(request::FilesMv { path, dest }, None) + self.request_empty(request::FilesMv { path, dest, flush }, None) .await } @@ -1184,8 +1189,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] @@ -1193,8 +1198,9 @@ impl IpfsClient { &self, path: &str, recursive: bool, + flush: bool, ) -> Result { - self.request_empty(request::FilesRm { path, recursive }, None) + self.request_empty(request::FilesRm { path, recursive, flush }, None) .await } @@ -1220,7 +1226,7 @@ impl IpfsClient { /// /// let client = IpfsClient::default(); /// let file = File::open("test.json").unwrap(); - /// let res = client.files_write("/test/file.json", true, true, true, 0, None, false, 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. @@ -1235,6 +1241,9 @@ impl IpfsClient { offset: i64, count: Option, raw_leaves: bool, + cid_version: i32, + hash: Option<&str>, + flush: bool, data: R, ) -> Result where @@ -1253,6 +1262,9 @@ impl IpfsClient { offset, count, raw_leaves, + cid_version, + hash, + flush, }, Some(form), ) @@ -1266,7 +1278,7 @@ impl IpfsClient { /// use std::fs::File; /// /// let client = IpfsClient::default(); - /// let res = client.files_chcid("/test/", 1, Some("sha3-512")); + /// let res = client.files_chcid("/test/", 1, Some("sha3-512"), true); /// ``` /// /// Not specifying a byte `count` writes the entire input. @@ -1277,9 +1289,10 @@ impl IpfsClient { path: &str, cid_version: i32, hash: Option<&str>, + flush: bool, ) -> Result { - self.request_empty(request::FilesChcid { path, cid_version, hash }, None) + self.request_empty(request::FilesChcid { path, cid_version, hash, flush }, None) .await } diff --git a/ipfs-api/src/request/files.rs b/ipfs-api/src/request/files.rs index bcf17cc..e70e04b 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> { @@ -48,6 +50,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 +71,8 @@ pub struct FilesMv<'a> { #[serde(rename = "arg")] pub dest: &'a str, + + pub flush: bool, } impl<'a> ApiRequest for FilesMv<'a> { @@ -88,6 +100,8 @@ pub struct FilesRm<'a> { pub path: &'a str, pub recursive: bool, + + pub flush: bool, } impl<'a> ApiRequest for FilesRm<'a> { @@ -122,6 +136,14 @@ pub struct FilesWrite<'a> { #[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> { @@ -138,6 +160,8 @@ pub struct FilesChcid<'a> { #[serde(rename = "cid-version")] pub cid_version: i32, + + pub flush: bool, } impl<'a> ApiRequest for FilesChcid<'a> { -- cgit v1.2.3 From 7a386ef41c5666dc98e75b5cec60f9f48e4450ae Mon Sep 17 00:00:00 2001 From: Julius Michaelis Date: Thu, 9 Jul 2020 20:41:11 +0900 Subject: add ipfs files stat --with-local --- ipfs-api/examples/mfs.rs | 4 ++-- ipfs-api/src/client/internal.rs | 6 +++--- ipfs-api/src/request/files.rs | 3 +++ ipfs-api/src/response/files.rs | 5 +++++ 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/ipfs-api/examples/mfs.rs b/ipfs-api/examples/mfs.rs index b53935c..2b20111 100644 --- a/ipfs-api/examples/mfs.rs +++ b/ipfs-api/examples/mfs.rs @@ -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); @@ -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); diff --git a/ipfs-api/src/client/internal.rs b/ipfs-api/src/client/internal.rs index f317fe8..8eaf595 100644 --- a/ipfs-api/src/client/internal.rs +++ b/ipfs-api/src/client/internal.rs @@ -1210,12 +1210,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 { - self.request(request::FilesStat { path }, None).await + pub async fn files_stat(&self, path: &str, with_local: bool) -> Result { + self.request(request::FilesStat { path, with_local }, None).await } /// Write to a mutable file in the filesystem. diff --git a/ipfs-api/src/request/files.rs b/ipfs-api/src/request/files.rs index e70e04b..b4b148f 100644 --- a/ipfs-api/src/request/files.rs +++ b/ipfs-api/src/request/files.rs @@ -112,6 +112,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> { diff --git a/ipfs-api/src/response/files.rs b/ipfs-api/src/response/files.rs index 76dc4a1..f27be1f 100644 --- a/ipfs-api/src/response/files.rs +++ b/ipfs-api/src/response/files.rs @@ -50,6 +50,11 @@ pub struct FilesStatResponse { #[serde(rename = "Type")] pub typ: String, + + #[serde(default)] + pub size_local: Option, + #[serde(default)] + pub local: Option, } pub type FilesWriteResponse = (); -- cgit v1.2.3 From 71f85fc597dd5c5128c61837f50b75a25a00699f Mon Sep 17 00:00:00 2001 From: Julius Michaelis Date: Thu, 9 Jul 2020 20:46:02 +0900 Subject: add ipfs files ls --long and force -U --- ipfs-api/src/client/internal.rs | 10 +++++----- ipfs-api/src/request/files.rs | 5 +++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ipfs-api/src/client/internal.rs b/ipfs-api/src/client/internal.rs index 8eaf595..d59288c 100644 --- a/ipfs-api/src/client/internal.rs +++ b/ipfs-api/src/client/internal.rs @@ -1107,19 +1107,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 { - self.request(request::FilesLs { path }, None).await + pub async fn files_ls(&self, path: Option<&str>, long: bool) -> Result { + self.request(request::FilesLs { path, long, unsorted: true }, None).await } /// Make directories in MFS. diff --git a/ipfs-api/src/request/files.rs b/ipfs-api/src/request/files.rs index b4b148f..109f107 100644 --- a/ipfs-api/src/request/files.rs +++ b/ipfs-api/src/request/files.rs @@ -38,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> { -- cgit v1.2.3 From 3905626f8f1c53a5ef933cd9bbefec31f8eb9355 Mon Sep 17 00:00:00 2001 From: Julius Michaelis Date: Sat, 11 Jul 2020 20:29:36 +0900 Subject: add builders for ipfs files {write, read, ls, rm, mkdir, chcid} --- ipfs-api/examples/mfs.rs | 8 +- ipfs-api/src/client/internal.rs | 271 +++++++++++++++++++++++++++++++--------- ipfs-api/src/request/files.rs | 90 ++++++++----- 3 files changed, 274 insertions(+), 95 deletions(-) diff --git a/ipfs-api/examples/mfs.rs b/ipfs-api/examples/mfs.rs index 2b20111..9deb90f 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, 0, None, true).await { + if let Err(e) = client.files_mkdir("/test", false).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, 0, None, true).await { + if let Err(e) = client.files_mkdir("/test/does/not/exist/yet", true).await { eprintln!("error making /test/does/not/exist/yet: {}", e); return; } @@ -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, false, 0, None, false, 0, None, true, src).await { + if let Err(e) = client.files_write("/test/mfs.rs", src).await { eprintln!("error writing source file /test/mfs.rs: {}", e); return; } @@ -79,7 +79,7 @@ async fn main() { eprintln!("removing /test..."); eprintln!(); - if let Err(e) = client.files_rm("/test", true, true).await { + if let Err(e) = client.files_rm("/test", true).await { eprintln!("error removing /test: {}", e); } diff --git a/ipfs-api/src/client/internal.rs b/ipfs-api/src/client/internal.rs index 885f6a4..420e896 100644 --- a/ipfs-api/src/client/internal.rs +++ b/ipfs-api/src/client/internal.rs @@ -39,6 +39,8 @@ use std::{ }; use tokio_util::codec::{Decoder, FramedRead}; +fn default() -> T { Default::default() } + const FILE_DESCRIPTOR_LIMIT: usize = 127; #[cfg(feature = "actix")] @@ -1145,19 +1147,50 @@ impl IpfsClient { self.request_empty(request::FilesFlush { path }, None).await } - /// List directories in MFS. Always passes `-U`. + /// List directories in MFS.. /// /// ```no_run /// use ipfs_api::IpfsClient; /// /// let client = IpfsClient::default(); - /// let res = client.files_ls(None, false); - /// let res = client.files_ls(Some("/tmp"), true); + /// let res = client.files_ls(None); + /// let res = client.files_ls(Some("/tmp")); /// ``` /// + /// Defaults to `-U`, so the output is unsorted. + /// #[inline] - pub async fn files_ls(&self, path: Option<&str>, long: bool) -> Result { - self.request(request::FilesLs { path, long, unsorted: true }, None).await + pub async fn files_ls(&self, path: Option<&str>) -> Result { + self.files_ls_with_options(request::FilesLs { path: path, .. default() }).await + } + + /// List directories in MFS.. + /// + /// ```no_run + /// let client = ipfs_api::IpfsClient::default(); + /// #[cfg(feature = "builder")] + /// let req = ipfs_api::request::FilesLs::builder() + /// // .path("/") // defaults to / + /// .unsorted(false) + /// .long(true) + /// .build(); + /// #[cfg(not(feature = "builder"))] + /// let req = ipfs_api::request::FilesLs { + /// path: None, // defaults to / + /// unsorted: Some(false), + /// long: Some(true), + /// }; + /// let res = client.files_ls_with_options(req); + /// ``` + /// + /// Defaults to `-U`, so the output is unsorted. + /// + #[inline] + pub async fn files_ls_with_options( + &self, + options: request::FilesLs<'_> + ) -> Result { + self.request(options, None).await } /// Make directories in MFS. @@ -1166,20 +1199,43 @@ impl IpfsClient { /// use ipfs_api::IpfsClient; /// /// let client = IpfsClient::default(); - /// let res = client.files_mkdir("/test", false, 0, None, true); - /// let res = client.files_mkdir("/test/nested/dir", true, 0, None, true); + /// let res = client.files_mkdir("/test", false); + /// let res = client.files_mkdir("/test/nested/dir", true); + /// ``` + /// + #[inline] + pub async fn files_mkdir(&self, path: &str, parents: bool) -> Result { + self.files_mkdir_with_options(request::FilesMkdir { path: path, parents: Some(parents), .. default() }).await + } + + /// Make directories in MFS. + /// + /// ```no_run + /// use ipfs_api::IpfsClient; + /// + /// let client = IpfsClient::default(); + /// #[cfg(feature = "builder")] + /// let req = ipfs_api::request::FilesMkdir::builder() + /// .path("/test/nested/dir") + /// .parents(true) + /// .flush(false) + /// .build(); + /// #[cfg(not(feature = "builder"))] + /// let req = ipfs_api::request::FilesMkdir { + /// path: "/test/nested/dir", + /// parents: Some(true), + /// flush: Some(false), + /// .. Default::default() + /// }; + /// let res = client.files_mkdir_with_options(req); /// ``` /// #[inline] - pub async fn files_mkdir( + pub async fn files_mkdir_with_options( &self, - path: &str, - parents: bool, - cid_version: i32, - hash: Option<&str>, - flush: bool, + options: request::FilesMkdir<'_> ) -> Result { - self.request_empty(request::FilesMkdir { path, parents, cid_version, hash, flush }, None) + self.request_empty(options, None) .await } @@ -1209,16 +1265,38 @@ impl IpfsClient { /// use ipfs_api::IpfsClient; /// /// let client = IpfsClient::default(); - /// let res = client.files_read("/test/file.json", 0, None); + /// let res = client.files_read("/test/file.json"); /// ``` /// - /// Not specifying a byte `count` reads to the end of the file. + #[inline] + pub fn files_read(&self, path: &str) -> impl Stream> { + self.files_read_with_options(request::FilesRead { path, .. request::FilesRead::default() }) + } + + /// Read a file in MFS. + /// + /// ```no_run + /// use ipfs_api::IpfsClient; + /// + /// let client = IpfsClient::default(); + /// #[cfg(feature = "builder")] + /// let req = ipfs_api::request::FilesRead::builder() + /// .path("/test/file.json") + /// .offset(1024) + /// .count(8) + /// .build(); + /// #[cfg(not(feature = "builder"))] + /// let req = ipfs_api::request::FilesRead { + /// path: "/test/file.json", + /// offset: Some(1024), + /// count: Some(8), + /// }; + /// let res = client.files_read_with_options(req); + /// ``` /// #[inline] - pub fn files_read(&self, path: &str, offset: i64, count: Option) -> impl Stream> { - impl_stream_api_response! { - (self, request::FilesRead { path, offset, count }, None) => request_stream_bytes - } + pub fn files_read_with_options(&self, options: request::FilesRead) -> impl Stream> { + impl_stream_api_response! { (self, options, None) => request_stream_bytes } } /// Remove a file in MFS. @@ -1227,8 +1305,8 @@ impl IpfsClient { /// use ipfs_api::IpfsClient; /// /// let client = IpfsClient::default(); - /// let res = client.files_rm("/test/dir", true, true); - /// let res = client.files_rm("/test/file.json", false, true); + /// let res = client.files_rm("/test/dir", true); + /// let res = client.files_rm("/test/file.json", false); /// ``` /// #[inline] @@ -1236,13 +1314,40 @@ impl IpfsClient { &self, path: &str, recursive: bool, - flush: bool, ) -> Result { - self.request_empty(request::FilesRm { path, recursive, flush }, None) - .await + self.files_rm_with_options(request::FilesRm { path, recursive: Some(recursive), .. default() }).await + } + + /// Remove a file in MFS. + /// + /// ```no_run + /// use ipfs_api::IpfsClient; + /// + /// let client = IpfsClient::default(); + /// #[cfg(feature = "builder")] + /// let req = ipfs_api::request::FilesRm::builder() + /// .path("/test/somefile.json") + /// .recursive(false) + /// .flush(false) + /// .build(); + /// #[cfg(not(feature = "builder"))] + /// let req = ipfs_api::request::FilesRm { + /// path: "/test/somefile.json", + /// recursive: Some(false), + /// flush: Some(false), + /// }; + /// let res = client.files_rm_with_options(req); + /// ``` + /// + #[inline] + pub async fn files_rm_with_options( + &self, + options: request::FilesRm<'_> + ) -> Result { + self.request_empty(options, None).await } - /// Display a file's status in MDFS. + /// Display a file's status in MFS. /// /// ```no_run /// use ipfs_api::IpfsClient; @@ -1264,24 +1369,53 @@ impl IpfsClient { /// /// let client = IpfsClient::default(); /// let file = File::open("test.json").unwrap(); - /// let res = client.files_write("/test/file.json", true, true, true, 0, None, false, 0, None, true, file); + /// let res = client.files_write("/test/file.json", file); /// ``` /// - /// Not specifying a byte `count` writes the entire input. + /// For convenience reasons, this defaults create and truncate to true /// #[inline] pub async fn files_write( &self, path: &str, - create: bool, - truncate: bool, - parents: bool, - offset: i64, - count: Option, - raw_leaves: bool, - cid_version: i32, - hash: Option<&str>, - flush: bool, + data: R, + ) -> Result + where + R: 'static + Read + Send + Sync, + { + self.files_write_with_options(request::FilesWrite { path, .. request::FilesWrite::default() }, data).await + } + + /// Write to a mutable file in the filesystem. + /// + /// ```no_run + /// let client = ipfs_api::IpfsClient::default(); + /// let data = std::io::Cursor::new((1..128).collect::>()); + /// #[cfg(feature = "builder")] + /// let req = ipfs_api::request::FilesWrite::builder() + /// .path("/test/outfile.bin") + /// .create(false) + /// .truncate(false) + /// .offset(1 << 20) + /// .flush(false) + /// // see FilesWriteBuilder for the full set of options + /// .build(); + /// #[cfg(not(feature = "builder"))] + /// let req = ipfs_api::request::FilesWrite { + /// path: "/test/outfile.bin", + /// create: Some(false), + /// truncate: Some(false), + /// offset: Some(1 << 20), + /// flush: Some(false), + /// .. Default::default() + /// }; + /// let res = client.files_write_with_options(req, data); + /// ``` + /// + #[inline] + pub async fn files_write_with_options( + &self, + options: request::FilesWrite<'_>, data: R, ) -> Result where @@ -1291,22 +1425,7 @@ impl IpfsClient { form.add_reader("data", data); - self.request_empty( - request::FilesWrite { - path, - create, - truncate, - parents, - offset, - count, - raw_leaves, - cid_version, - hash, - flush, - }, - Some(form), - ) - .await + self.request_empty(options, Some(form)).await } /// Change the cid version or hash function of the root node of a given path. @@ -1316,7 +1435,7 @@ impl IpfsClient { /// use std::fs::File; /// /// let client = IpfsClient::default(); - /// let res = client.files_chcid("/test/", 1, Some("sha3-512"), true); + /// let res = client.files_chcid("/test/", 1); /// ``` /// /// Not specifying a byte `count` writes the entire input. @@ -1326,12 +1445,48 @@ impl IpfsClient { &self, path: &str, cid_version: i32, - hash: Option<&str>, - flush: bool, ) -> Result { - self.request_empty(request::FilesChcid { path, cid_version, hash, flush }, None) - .await + self.request_empty(request::FilesChcid { + path: Some(path), + cid_version: Some(cid_version), + .. default() + }, None).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(); + /// #[cfg(feature = "builder")] + /// let req = ipfs_api::request::FilesChcid::builder() + /// .path("/test/") + /// .cid_version(1) + /// .hash("sha3-512") + /// .flush(true) + /// .build(); + /// #[cfg(not(feature = "builder"))] + /// let req = ipfs_api::request::FilesChcid { + /// path: Some("/test/"), + /// cid_version: Some(1), + /// hash: Some("sha3-512"), + /// flush: Some(false), + /// }; + /// let res = client.files_chcid_with_options(req); + /// ``` + /// + /// Not specifying a byte `count` writes the entire input. + /// + #[inline] + pub async fn files_chcid_with_options( + &self, + options: request::FilesChcid<'_> + ) -> Result + { + self.request_empty(options, None).await } /// List blocks that are both in the filestore and standard block storage. diff --git a/ipfs-api/src/request/files.rs b/ipfs-api/src/request/files.rs index 109f107..2a7b996 100644 --- a/ipfs-api/src/request/files.rs +++ b/ipfs-api/src/request/files.rs @@ -34,35 +34,43 @@ impl<'a> ApiRequest for FilesFlush<'a> { const PATH: &'static str = "/files/flush"; } -#[derive(Serialize)] +#[cfg_attr(feature = "builder", derive(TypedBuilder))] +#[derive(Serialize, Default)] pub struct FilesLs<'a> { #[serde(rename = "arg")] + #[cfg_attr(feature = "builder", builder(default, setter(strip_option)))] pub path: Option<&'a str>, - pub long: bool, + #[cfg_attr(feature = "builder", builder(default, setter(strip_option)))] + pub long: Option, + #[cfg_attr(feature = "builder", builder(default, setter(strip_option)))] #[serde(rename = "U")] - pub unsorted: bool, + pub unsorted: Option, } impl<'a> ApiRequest for FilesLs<'a> { const PATH: &'static str = "/files/ls"; } -#[derive(Serialize)] +#[cfg_attr(feature = "builder", derive(TypedBuilder))] +#[derive(Serialize, Default)] +#[serde(rename_all = "kebab-case")] pub struct FilesMkdir<'a> { #[serde(rename = "arg")] pub path: &'a str, - pub parents: bool, + #[cfg_attr(feature = "builder", builder(default, setter(strip_option)))] + pub parents: Option, - #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "builder", builder(default, setter(strip_option)))] pub hash: Option<&'a str>, - #[serde(rename = "cid-version")] - pub cid_version: i32, + #[cfg_attr(feature = "builder", builder(default, setter(strip_option)))] + pub cid_version: Option, - pub flush: bool, + #[cfg_attr(feature = "builder", builder(default, setter(strip_option)))] + pub flush: Option, } impl<'a> ApiRequest for FilesMkdir<'a> { @@ -84,14 +92,16 @@ impl<'a> ApiRequest for FilesMv<'a> { const PATH: &'static str = "/files/mv"; } -#[derive(Serialize)] +#[cfg_attr(feature = "builder", derive(TypedBuilder))] +#[derive(Serialize, Default)] pub struct FilesRead<'a> { #[serde(rename = "arg")] pub path: &'a str, - pub offset: i64, + #[cfg_attr(feature = "builder", builder(default, setter(strip_option)))] + pub offset: Option, - #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "builder", builder(default, setter(strip_option)))] pub count: Option, } @@ -99,14 +109,17 @@ impl<'a> ApiRequest for FilesRead<'a> { const PATH: &'static str = "/files/read"; } -#[derive(Serialize)] +#[cfg_attr(feature = "builder", derive(TypedBuilder))] +#[derive(Serialize, Default)] pub struct FilesRm<'a> { #[serde(rename = "arg")] pub path: &'a str, - pub recursive: bool, + #[cfg_attr(feature = "builder", builder(default, setter(strip_option)))] + pub recursive: Option, - pub flush: bool, + #[cfg_attr(feature = "builder", builder(default, setter(strip_option)))] + pub flush: Option, } impl<'a> ApiRequest for FilesRm<'a> { @@ -126,50 +139,61 @@ impl<'a> ApiRequest for FilesStat<'a> { const PATH: &'static str = "/files/stat"; } -#[derive(Serialize)] +#[cfg_attr(feature = "builder", derive(TypedBuilder))] +#[derive(Serialize, Default)] +#[serde(rename_all = "kebab-case")] pub struct FilesWrite<'a> { #[serde(rename = "arg")] pub path: &'a str, - pub create: bool, + #[cfg_attr(feature = "builder", builder(default, setter(strip_option)))] + pub create: Option, - pub truncate: bool, + #[cfg_attr(feature = "builder", builder(default, setter(strip_option)))] + pub truncate: Option, - pub parents: bool, + #[cfg_attr(feature = "builder", builder(default, setter(strip_option)))] + pub parents: Option, - pub offset: i64, + #[cfg_attr(feature = "builder", builder(default, setter(strip_option)))] + pub offset: Option, - #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "builder", builder(default, setter(strip_option)))] pub count: Option, - #[serde(rename = "raw-leaves")] - pub raw_leaves: bool, + #[cfg_attr(feature = "builder", builder(default, setter(strip_option)))] + pub raw_leaves: Option, - #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "builder", builder(default, setter(strip_option)))] pub hash: Option<&'a str>, - #[serde(rename = "cid-version")] - pub cid_version: i32, + #[cfg_attr(feature = "builder", builder(default, setter(strip_option)))] + pub cid_version: Option, - pub flush: bool, + #[cfg_attr(feature = "builder", builder(default, setter(strip_option)))] + pub flush: Option, } impl<'a> ApiRequest for FilesWrite<'a> { const PATH: &'static str = "/files/write"; } -#[derive(Serialize)] +#[cfg_attr(feature = "builder", derive(TypedBuilder))] +#[derive(Serialize, Default)] +#[serde(rename_all = "kebab-case")] pub struct FilesChcid<'a> { + #[cfg_attr(feature = "builder", builder(default, setter(strip_option)))] #[serde(rename = "arg")] - pub path: &'a str, + pub path: Option<&'a str>, - #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "builder", builder(default, setter(strip_option)))] pub hash: Option<&'a str>, - #[serde(rename = "cid-version")] - pub cid_version: i32, + #[cfg_attr(feature = "builder", builder(default, setter(strip_option)))] + pub cid_version: Option, - pub flush: bool, + #[cfg_attr(feature = "builder", builder(default, setter(strip_option)))] + pub flush: Option, } impl<'a> ApiRequest for FilesChcid<'a> { -- cgit v1.2.3 From 50718691022f479e144ab4b06a7f74e84cd967a7 Mon Sep 17 00:00:00 2001 From: Julius Michaelis Date: Mon, 13 Jul 2020 14:47:54 +0900 Subject: Revert changes to files_* since extra parameters can be passed through *_with_options and adding *_with_options can be a non-breaking change --- ipfs-api/examples/mfs.rs | 6 +++--- ipfs-api/src/client/internal.rs | 42 +++++++++++++++++++++++------------------ ipfs-api/src/request/files.rs | 14 +++++++------- 3 files changed, 34 insertions(+), 28 deletions(-) diff --git a/ipfs-api/examples/mfs.rs b/ipfs-api/examples/mfs.rs index 9deb90f..3d6419c 100644 --- a/ipfs-api/examples/mfs.rs +++ b/ipfs-api/examples/mfs.rs @@ -47,7 +47,7 @@ async fn main() { eprintln!("getting status of /test/does..."); eprintln!(); - match client.files_stat("/test/does", false).await { + match client.files_stat("/test/does").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", src).await { + if let Err(e) = client.files_write("/test/mfs.rs", true, 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", false).await { + match client.files_stat("/test/mfs.rs").await { Ok(stat) => print_stat(stat), Err(e) => { eprintln!("error getting status of /test/mfs.rs: {}", e); diff --git a/ipfs-api/src/client/internal.rs b/ipfs-api/src/client/internal.rs index 420e896..d652458 100644 --- a/ipfs-api/src/client/internal.rs +++ b/ipfs-api/src/client/internal.rs @@ -1115,7 +1115,7 @@ impl IpfsClient { /// use ipfs_api::IpfsClient; /// /// let client = IpfsClient::default(); - /// let res = client.files_cp("/path/to/file", "/dest", true); + /// let res = client.files_cp("/path/to/file", "/dest"); /// ``` /// #[inline] @@ -1123,9 +1123,8 @@ impl IpfsClient { &self, path: &str, dest: &str, - flush: bool, ) -> Result { - self.request_empty(request::FilesCp { path, dest, flush }, None) + self.request_empty(request::FilesCp { path, dest, .. default() }, None) .await } @@ -1147,7 +1146,7 @@ impl IpfsClient { self.request_empty(request::FilesFlush { path }, None).await } - /// List directories in MFS.. + /// List directories in MFS. /// /// ```no_run /// use ipfs_api::IpfsClient; @@ -1157,8 +1156,6 @@ impl IpfsClient { /// let res = client.files_ls(Some("/tmp")); /// ``` /// - /// Defaults to `-U`, so the output is unsorted. - /// #[inline] pub async fn files_ls(&self, path: Option<&str>) -> Result { self.files_ls_with_options(request::FilesLs { path: path, .. default() }).await @@ -1204,8 +1201,12 @@ impl IpfsClient { /// ``` /// #[inline] - pub async fn files_mkdir(&self, path: &str, parents: bool) -> Result { - self.files_mkdir_with_options(request::FilesMkdir { path: path, parents: Some(parents), .. default() }).await + pub async fn files_mkdir( + &self, + path: &str, + parents: bool, + ) -> Result { + self.files_mkdir_with_options(request::FilesMkdir { path, parents: Some(parents), .. default() }).await } /// Make directories in MFS. @@ -1245,7 +1246,7 @@ impl IpfsClient { /// use ipfs_api::IpfsClient; /// /// let client = IpfsClient::default(); - /// let res = client.files_mv("/test/tmp.json", "/test/file.json", true); + /// let res = client.files_mv("/test/tmp.json", "/test/file.json"); /// ``` /// #[inline] @@ -1253,9 +1254,8 @@ impl IpfsClient { &self, path: &str, dest: &str, - flush: bool, ) -> Result { - self.request_empty(request::FilesMv { path, dest, flush }, None) + self.request_empty(request::FilesMv { path, dest, .. default() }, None) .await } @@ -1353,12 +1353,12 @@ impl IpfsClient { /// use ipfs_api::IpfsClient; /// /// let client = IpfsClient::default(); - /// let res = client.files_stat("/test/file.json", false); + /// let res = client.files_stat("/test/file.json"); /// ``` /// #[inline] - pub async fn files_stat(&self, path: &str, with_local: bool) -> Result { - self.request(request::FilesStat { path, with_local }, None).await + pub async fn files_stat(&self, path: &str) -> Result { + self.request(request::FilesStat { path, .. default() }, None).await } /// Write to a mutable file in the filesystem. @@ -1369,21 +1369,27 @@ impl IpfsClient { /// /// let client = IpfsClient::default(); /// let file = File::open("test.json").unwrap(); - /// let res = client.files_write("/test/file.json", file); + /// let res = client.files_write("/test/file.json", true, true, file); /// ``` /// - /// For convenience reasons, this defaults create and truncate to true - /// #[inline] pub async fn files_write( &self, path: &str, + create: bool, + truncate: bool, data: R, ) -> Result where R: 'static + Read + Send + Sync, { - self.files_write_with_options(request::FilesWrite { path, .. request::FilesWrite::default() }, data).await + let options = request::FilesWrite { + path, + create: Some(create), + truncate: Some(truncate), + .. request::FilesWrite::default() + }; + self.files_write_with_options(options, data).await } /// Write to a mutable file in the filesystem. diff --git a/ipfs-api/src/request/files.rs b/ipfs-api/src/request/files.rs index 2a7b996..498faa9 100644 --- a/ipfs-api/src/request/files.rs +++ b/ipfs-api/src/request/files.rs @@ -9,7 +9,7 @@ use crate::request::ApiRequest; use crate::serde::Serialize; -#[derive(Serialize)] +#[derive(Serialize, Default)] pub struct FilesCp<'a> { #[serde(rename = "arg")] pub path: &'a str, @@ -17,7 +17,7 @@ pub struct FilesCp<'a> { #[serde(rename = "arg")] pub dest: &'a str, - pub flush: bool, + pub flush: Option, } impl<'a> ApiRequest for FilesCp<'a> { @@ -77,7 +77,7 @@ impl<'a> ApiRequest for FilesMkdir<'a> { const PATH: &'static str = "/files/mkdir"; } -#[derive(Serialize)] +#[derive(Serialize, Default)] pub struct FilesMv<'a> { #[serde(rename = "arg")] pub path: &'a str, @@ -85,7 +85,7 @@ pub struct FilesMv<'a> { #[serde(rename = "arg")] pub dest: &'a str, - pub flush: bool, + pub flush: Option, } impl<'a> ApiRequest for FilesMv<'a> { @@ -126,13 +126,13 @@ impl<'a> ApiRequest for FilesRm<'a> { const PATH: &'static str = "/files/rm"; } -#[derive(Serialize)] +#[derive(Serialize, Default)] +#[serde(rename_all = "kebab-case")] pub struct FilesStat<'a> { #[serde(rename = "arg")] pub path: &'a str, - #[serde(rename = "with-local")] - pub with_local: bool, + pub with_local: Option, } impl<'a> ApiRequest for FilesStat<'a> { -- cgit v1.2.3 From 716e34de0419ec0a2533fe6b5b20cab3d11405b2 Mon Sep 17 00:00:00 2001 From: Julius Michaelis Date: Mon, 13 Jul 2020 15:21:17 +0900 Subject: ipfs files: add *_with_options for currently unusable parameters --- ipfs-api/src/client/internal.rs | 72 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 5 deletions(-) diff --git a/ipfs-api/src/client/internal.rs b/ipfs-api/src/client/internal.rs index d652458..0817ada 100644 --- a/ipfs-api/src/client/internal.rs +++ b/ipfs-api/src/client/internal.rs @@ -1124,10 +1124,27 @@ impl IpfsClient { path: &str, dest: &str, ) -> Result { - self.request_empty(request::FilesCp { path, dest, .. default() }, None) + self.files_cp_with_options(request::FilesCp { path, dest, .. default() }) .await } + /// Copy files into MFS. + /// + /// ```no_run + /// use ipfs_api::IpfsClient; + /// + /// let client = IpfsClient::default(); + /// let res = client.files_cp("/path/to/file", "/dest"); + /// ``` + /// + #[inline] + pub async fn files_cp_with_options( + &self, + options: request::FilesCp<'_>, + ) -> Result { + self.request_empty(options, None).await + } + /// Flush a path's data to disk. /// /// ```no_run @@ -1236,8 +1253,7 @@ impl IpfsClient { &self, options: request::FilesMkdir<'_> ) -> Result { - self.request_empty(options, None) - .await + self.request_empty(options, None).await } /// Copy files into MFS. @@ -1255,7 +1271,31 @@ impl IpfsClient { path: &str, dest: &str, ) -> Result { - self.request_empty(request::FilesMv { path, dest, .. default() }, None) + self.files_mv_with_options(request::FilesMv { path, dest, .. default() }) + .await + } + + /// Copy files into MFS. + /// + /// ```no_run + /// use ipfs_api::IpfsClient; + /// + /// let client = IpfsClient::default(); + /// let res = client.files_mv_with_options( + /// ipfs_api::request::FilesMv { + /// path: "/test/tmp.json", + /// dest: "/test/file.json", + /// flush: Some(false), + /// } + /// ); + /// ``` + /// + #[inline] + pub async fn files_mv_with_options( + &self, + options: request::FilesMv<'_>, + ) -> Result { + self.request_empty(options, None) .await } @@ -1358,7 +1398,29 @@ impl IpfsClient { /// #[inline] pub async fn files_stat(&self, path: &str) -> Result { - self.request(request::FilesStat { path, .. default() }, None).await + self.files_stat_with_options(request::FilesStat { path, .. default() }).await + } + + /// Display a file's status in MFS. + /// + /// ```no_run + /// use ipfs_api::IpfsClient; + /// + /// let client = IpfsClient::default(); + /// let res = client.files_stat_with_options( + /// ipfs_api::request::FilesStat { + /// path: "/test/dir/", + /// with_local: Some(true), + /// } + /// ); + /// ``` + /// + #[inline] + pub async fn files_stat_with_options( + &self, + options: request::FilesStat<'_> + ) -> Result { + self.request(options, None).await } /// Write to a mutable file in the filesystem. -- cgit v1.2.3 From a3ad2e6bd9b8ed05587ea990c2136953ad2fd50f Mon Sep 17 00:00:00 2001 From: Julius Michaelis Date: Mon, 13 Jul 2020 15:22:33 +0900 Subject: Revert version bump "0.7.2 -> 0.8.0" This should now be compatible with 0.7. This reverts commit 208a23371318ef9f61a27301093ea6667996102e. --- Cargo.lock | 2 +- README.md | 4 ++-- ipfs-api/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2f3af8c..22ab27f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -956,7 +956,7 @@ dependencies = [ [[package]] name = "ipfs-api" -version = "0.8.0" +version = "0.7.2" 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 7427c36..254d89f 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.8" +ipfs-api = "0.7.2" ``` You can use `actix-web` as a backend instead of `hyper`. ```toml [dependencies] -ipfs-api = { version = "0.8", features = ["actix"], default-features = false } +ipfs-api = { version = "0.7.2", features = ["actix"], default-features = false } ``` ### Examples diff --git a/ipfs-api/Cargo.toml b/ipfs-api/Cargo.toml index 76deb6e..9f2ca23 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.8.0" +version = "0.7.2" readme = "../README.md" license = "MIT OR Apache-2.0" -- cgit v1.2.3