├── .github └── workflows │ └── rust.yml ├── .gitignore ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── Makefile ├── README.md ├── README.tpl ├── ipfs-api-backend-actix ├── Cargo.toml └── src │ ├── backend.rs │ ├── error.rs │ └── lib.rs ├── ipfs-api-backend-hyper ├── Cargo.toml └── src │ ├── backend.rs │ ├── error.rs │ └── lib.rs ├── ipfs-api-examples ├── Cargo.toml ├── examples │ ├── add_file.rs │ ├── add_file_piped_from_command.rs │ ├── add_tar.rs │ ├── app_error_enum.rs │ ├── basic_auth.rs │ ├── bootstrap_default.rs │ ├── cat.rs │ ├── check_file_local.rs │ ├── config.rs │ ├── dag.rs │ ├── default_config.json │ ├── dns.rs │ ├── get_commands.rs │ ├── get_stats.rs │ ├── get_swarm.rs │ ├── get_version.rs │ ├── log_tail.rs │ ├── mfs.rs │ ├── ping_peer.rs │ ├── pubsub.rs │ ├── replace_config.rs │ └── resolve_name.rs └── src │ └── lib.rs ├── ipfs-api-prelude ├── Cargo.toml └── src │ ├── api.rs │ ├── backend.rs │ ├── error.rs │ ├── from_uri.rs │ ├── global_opts.rs │ ├── header.rs │ ├── lib.rs │ ├── read.rs │ ├── request │ ├── add.rs │ ├── bitswap.rs │ ├── block.rs │ ├── bootstrap.rs │ ├── cat.rs │ ├── commands.rs │ ├── config.rs │ ├── dag.rs │ ├── dht.rs │ ├── diag.rs │ ├── dns.rs │ ├── file.rs │ ├── files.rs │ ├── filestore.rs │ ├── get.rs │ ├── id.rs │ ├── key.rs │ ├── log.rs │ ├── ls.rs │ ├── mod.rs │ ├── name.rs │ ├── object.rs │ ├── pin.rs │ ├── ping.rs │ ├── pubsub.rs │ ├── refs.rs │ ├── shutdown.rs │ ├── stats.rs │ ├── swarm.rs │ ├── swarm_connect.rs │ ├── tar.rs │ └── version.rs │ └── response │ ├── add.rs │ ├── bitswap.rs │ ├── block.rs │ ├── bootstrap.rs │ ├── commands.rs │ ├── config.rs │ ├── dag.rs │ ├── dht.rs │ ├── diag.rs │ ├── dns.rs │ ├── error.rs │ ├── file.rs │ ├── files.rs │ ├── filestore.rs │ ├── id.rs │ ├── key.rs │ ├── log.rs │ ├── ls.rs │ ├── mod.rs │ ├── mount.rs │ ├── name.rs │ ├── object.rs │ ├── pin.rs │ ├── ping.rs │ ├── pubsub.rs │ ├── refs.rs │ ├── repo.rs │ ├── resolve.rs │ ├── serde.rs │ ├── shutdown.rs │ ├── stats.rs │ ├── swarm.rs │ ├── swarm_connect.rs │ ├── tar.rs │ ├── tests │ ├── v0_bitswap_stat_0.json │ ├── v0_block_stat_0.json │ ├── v0_bootstrap_list_0.json │ ├── v0_commands_0.json │ ├── v0_dag_get_0.json │ ├── v0_file_ls_0.json │ ├── v0_file_ls_1.json │ ├── v0_files_ls_0.json │ ├── v0_files_stat_0.json │ ├── v0_id_0.json │ ├── v0_key_gen_0.json │ ├── v0_key_list_0.json │ ├── v0_key_rename_0.json │ ├── v0_key_rm_0.json │ ├── v0_log_ls_0.json │ ├── v0_ls_0.json │ ├── v0_ls_1.json │ ├── v0_mount_0.json │ ├── v0_name_resolve_0.json │ ├── v0_object_diff_0.json │ ├── v0_object_links_0.json │ ├── v0_object_stat_0.json │ ├── v0_pin_add_0.json │ ├── v0_pin_ls_0.json │ ├── v0_ping_0.json │ ├── v0_ping_1.json │ ├── v0_ping_2.json │ ├── v0_pubsub_ls_0.json │ ├── v0_pubsub_ls_1.json │ ├── v0_pubsub_peers_0.json │ ├── v0_pubsub_sub_0.json │ ├── v0_pubsub_sub_1.json │ ├── v0_refs_local_0.json │ ├── v0_repo_gc_0.json │ ├── v0_repo_stat_0.json │ ├── v0_repo_verify_0.json │ ├── v0_repo_verify_1.json │ ├── v0_repo_version_0.json │ ├── v0_resolve_0.json │ ├── v0_stats_bw_0.json │ ├── v0_swarm_addrs_local_0.json │ ├── v0_swarm_connect_0.json │ ├── v0_swarm_peers_0.json │ ├── v0_swarm_peers_1.json │ ├── v0_swarm_peers_2.json │ ├── v0_tar_add_0.json │ ├── v0_version_0.json │ └── v0_version_1.json │ └── version.rs ├── ipfs-api-versions ├── Cargo.toml └── src │ └── lib.rs ├── ipfs-api ├── Cargo.toml ├── src │ └── lib.rs └── tests │ ├── test_backend.rs │ ├── test_basic_auth.rs │ ├── test_get_version.rs │ └── test_support │ ├── client.rs │ ├── container.rs │ ├── default-template.conf │ ├── errors.rs │ ├── images.rs │ ├── lib.rs │ └── resources.rs ├── rust-toolchain.toml └── rustfmt.toml /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | name: Rust 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | env: 10 | CARGO_TERM_COLOR: always 11 | 12 | jobs: 13 | build-actix: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | - name: Build (Actix) 20 | run: cd ipfs-api; cargo build --verbose --features with-actix --no-default-features 21 | - name: Build examples (Actix) 22 | run: cargo build --verbose --examples --no-default-features --features with-actix 23 | - name: Build tests (Actix) 24 | run: cd ipfs-api; cargo test --verbose --features with-actix --no-default-features --no-run 25 | - name: Run tests (Actix) 26 | run: cd ipfs-api; cargo test --verbose --features with-actix --no-default-features 27 | 28 | build-default: 29 | 30 | runs-on: ubuntu-latest 31 | 32 | steps: 33 | - uses: actions/checkout@v2 34 | - name: Build 35 | run: cargo build --verbose 36 | - name: Build examples 37 | run: cargo build --verbose --examples 38 | - name: Build tests 39 | run: cargo test --verbose --no-run 40 | - name: Run tests 41 | run: cargo test --verbose 42 | 43 | build-hyper: 44 | 45 | runs-on: ubuntu-latest 46 | 47 | steps: 48 | - uses: actions/checkout@v2 49 | 50 | - name: Build (Hyper with tls) 51 | run: cd ipfs-api; cargo build --verbose --features with-hyper-tls --no-default-features 52 | - name: Build examples (Hyper with tls) 53 | run: cargo build --verbose --examples --no-default-features --features with-hyper-tls 54 | - name: Build tests (Hyper with tls) 55 | run: cargo test --verbose --features with-hyper-tls --no-default-features --no-run 56 | - name: Run tests (Hyper with tls) 57 | run: cargo test --verbose --features with-hyper-tls --no-default-features 58 | 59 | - name: Build (Hyper with rustls) 60 | run: cd ipfs-api; cargo build --verbose --features with-hyper-rustls --no-default-features 61 | - name: Build examples (Hyper with rustls) 62 | run: cargo build --verbose --examples --no-default-features --features with-hyper-rustls 63 | 64 | - name: Build (Hyper with Send trait) 65 | run: cd ipfs-api-backend-hyper; cargo build --verbose --features with-send-sync 66 | 67 | other: 68 | 69 | runs-on: ubuntu-latest 70 | 71 | steps: 72 | - uses: actions/checkout@v2 73 | - name: Format (Default) 74 | run: cargo fmt --all -- --check 75 | - name: Clippy 76 | shell: bash 77 | run: cargo clippy --all-targets -- -D warnings 78 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .envrc 2 | .idea 3 | .tmpipfs 4 | /target/ 5 | **/target/ 6 | **/*.rs.bk 7 | Cargo.lock 8 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "2" 3 | 4 | members = [ 5 | "ipfs-api", 6 | "ipfs-api-backend-actix", 7 | "ipfs-api-backend-hyper", 8 | "ipfs-api-examples", 9 | "ipfs-api-prelude", 10 | "ipfs-api-versions", 11 | ] 12 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any 2 | person obtaining a copy of this software and associated 3 | documentation files (the "Software"), to deal in the 4 | Software without restriction, including without 5 | limitation the rights to use, copy, modify, merge, 6 | publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software 8 | is furnished to do so, subject to the following 9 | conditions: 10 | 11 | The above copyright notice and this permission notice 12 | shall be included in all copies or substantial portions 13 | of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 16 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 17 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 19 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 22 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SHELL := /bin/bash 2 | 3 | IPFS_API_PATH := ipfs-api 4 | 5 | CARGO_BIN := $(shell which cargo) 6 | 7 | WORKSPACE_CARGO_FILE := Cargo.toml 8 | 9 | README.md: README.tpl $(WORKSPACE_CARGO_FILE) $(IPFS_API_PATH)/Cargo.toml $(IPFS_API_PATH)/src/lib.rs 10 | $(CARGO_BIN) readme -r $(IPFS_API_PATH) -t ../README.tpl -o ../$@ 11 | -------------------------------------------------------------------------------- /README.tpl: -------------------------------------------------------------------------------- 1 | {{badges}} 2 | 3 | # {{crate}} 4 | 5 | ### Components 6 | 7 | | Name | Documentation | Crate | 8 | | ----------------------- | ------------------------------------------------ | --------------------------------------------------- | 9 | | ipfs-api-prelude | [![Docs][prelude docs badge]][prelude docs link] | [![Crate][prelude crate badge]][prelude crate link] | 10 | | ipfs-api-backend-actix | [![Docs][actix docs badge]][actix docs link] | [![Crate][actix crate badge]][actix crate link] | 11 | | ipfs-api-backend-hyper | [![Docs][hyper docs badge]][hyper docs link] | [![Crate][hyper crate badge]][hyper crate link] | 12 | | ipfs-api (deprecated) | [![Docs][old docs badge]][old docs link] | [![Crate][old crate badge]][old crate link] | 13 | 14 | {{readme}} 15 | 16 | ## License 17 | 18 | Licensed under either of 19 | 20 | * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) 21 | * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) 22 | 23 | at your option. 24 | 25 | ### Contribution 26 | 27 | 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. 28 | 29 | [prelude docs badge]: https://img.shields.io/docsrs/ipfs-api-prelude/latest "ipfs-api-prelude documentation" 30 | [prelude docs link]: https://docs.rs/ipfs-api-prelude 31 | [prelude crate badge]: https://img.shields.io/crates/v/ipfs-api-prelude.svg "ipfs-api-prelude crates.io" 32 | [prelude crate link]: https://crates.io/crates/ipfs-api-prelude 33 | [actix docs badge]: https://docs.rs/ipfs-api-backend-actix/badge.svg "ipfs-api-backend-actix documentation" 34 | [actix docs link]: https://docs.rs/ipfs-api-backend-actix 35 | [actix crate badge]: https://img.shields.io/crates/v/ipfs-api-backend-actix.svg "ipfs-api-backend-actix crates.io" 36 | [actix crate link]: https://crates.io/crates/ipfs-api-backend-actix 37 | [hyper docs badge]: https://docs.rs/ipfs-api-backend-hyper/badge.svg "ipfs-api-backend-hyper documentation" 38 | [hyper docs link]: https://docs.rs/ipfs-api-backend-hyper 39 | [hyper crate badge]: https://img.shields.io/crates/v/ipfs-api-backend-hyper.svg "ipfs-api-backend-hyper crates.io" 40 | [hyper crate link]: https://crates.io/crates/ipfs-api-backend-hyper 41 | [old docs badge]: https://docs.rs/ipfs-api/badge.svg "ipfs-api (deprecated) documentation" 42 | [old docs link]: https://docs.rs/ipfs-api 43 | [old crate badge]: https://img.shields.io/crates/v/ipfs-api.svg "ipfs-api (deprecated) crates.io" 44 | [old crate link]: https://crates.io/crates/ipfs-api 45 | -------------------------------------------------------------------------------- /ipfs-api-backend-actix/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ipfs-api-backend-actix" 3 | description = "Actix implementation of IPFS HTTP API" 4 | authors = ["Ferris Tseng "] 5 | edition = "2021" 6 | documentation = "https://docs.rs/ipfs-api" 7 | repository = "https://github.com/ferristseng/rust-ipfs-api" 8 | keywords = ["ipfs"] 9 | categories = ["filesystem", "web-programming"] 10 | version = "0.7.0" 11 | readme = "../README.md" 12 | license = "MIT OR Apache-2.0" 13 | 14 | [badges] 15 | github = { repository = "ferristseng/rust-ipfs-api", workflow = "Rust" } 16 | maintenance = { status = "passively-maintained" } 17 | 18 | [features] 19 | with-builder = ["ipfs-api-prelude/with-builder"] 20 | 21 | [dependencies] 22 | actix-http = "3" 23 | actix-multipart-rfc7578 = "0.10" 24 | actix-tls = "3" 25 | awc = "3" 26 | async-trait = "0.1" 27 | bytes = "1" 28 | futures = "0.3" 29 | http = "0.2" 30 | ipfs-api-prelude = { version = "0.6", path = "../ipfs-api-prelude" } 31 | thiserror = "1" 32 | -------------------------------------------------------------------------------- /ipfs-api-backend-actix/src/backend.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::error::Error; 10 | use async_trait::async_trait; 11 | use awc::Client; 12 | use bytes::Bytes; 13 | use futures::{FutureExt, StreamExt, TryFutureExt, TryStreamExt}; 14 | use http::{ 15 | header::{HeaderName, HeaderValue}, 16 | uri::Scheme, 17 | StatusCode, Uri, 18 | }; 19 | use ipfs_api_prelude::{ApiRequest, Backend, BoxStream, TryFromUri}; 20 | use multipart::client::multipart; 21 | use std::time::Duration; 22 | 23 | const ACTIX_REQUEST_TIMEOUT: Duration = Duration::from_secs(90); 24 | 25 | pub struct ActixBackend { 26 | base: Uri, 27 | client: Client, 28 | 29 | /// Username and password 30 | credentials: Option<(String, String)>, 31 | } 32 | 33 | impl Default for ActixBackend { 34 | /// Creates an `IpfsClient` connected to the endpoint specified in ~/.ipfs/api. 35 | /// If not found, tries to connect to `localhost:5001`. 36 | /// 37 | fn default() -> Self { 38 | Self::from_ipfs_config() 39 | .unwrap_or_else(|| Self::from_host_and_port(Scheme::HTTP, "localhost", 5001).unwrap()) 40 | } 41 | } 42 | 43 | impl TryFromUri for ActixBackend { 44 | fn build_with_base_uri(base: Uri) -> Self { 45 | let client = Client::default(); 46 | 47 | ActixBackend { 48 | base, 49 | client, 50 | credentials: None, 51 | } 52 | } 53 | } 54 | 55 | impl ActixBackend { 56 | pub fn with_credentials(self, username: U, password: P) -> Self 57 | where 58 | U: Into, 59 | P: Into, 60 | { 61 | Self { 62 | base: self.base, 63 | client: self.client, 64 | credentials: Some((username.into(), password.into())), 65 | } 66 | } 67 | } 68 | 69 | #[async_trait(?Send)] 70 | impl Backend for ActixBackend { 71 | type HttpRequest = awc::SendClientRequest; 72 | 73 | type HttpResponse = awc::ClientResponse>; 74 | 75 | type Error = Error; 76 | 77 | fn with_credentials(self, username: U, password: P) -> Self 78 | where 79 | U: Into, 80 | P: Into, 81 | { 82 | (self as ActixBackend).with_credentials(username, password) 83 | } 84 | 85 | fn build_base_request( 86 | &self, 87 | req: Req, 88 | form: Option>, 89 | ) -> Result 90 | where 91 | Req: ApiRequest, 92 | { 93 | let url = req.absolute_url(&self.base)?; 94 | let req = self.client.request(Req::METHOD, url); 95 | let req = if let Some((username, password)) = &self.credentials { 96 | req.basic_auth(username, password) 97 | } else { 98 | req 99 | }; 100 | let req = if let Some(form) = form { 101 | req.content_type(form.content_type()) 102 | .send_body(multipart::Body::from(form)) 103 | } else { 104 | req.timeout(ACTIX_REQUEST_TIMEOUT).send() 105 | }; 106 | 107 | Ok(req) 108 | } 109 | 110 | fn get_header(res: &Self::HttpResponse, key: HeaderName) -> Option<&HeaderValue> { 111 | res.headers().get(key) 112 | } 113 | 114 | async fn request_raw( 115 | &self, 116 | req: Req, 117 | form: Option>, 118 | ) -> Result<(StatusCode, Bytes), Self::Error> 119 | where 120 | Req: ApiRequest, 121 | { 122 | let req = self.build_base_request(req, form)?; 123 | let mut res = req.await?; 124 | let status = res.status(); 125 | let body = res.body().await?; 126 | 127 | // FIXME: Actix compat with bytes 1.0 128 | Ok((status, body)) 129 | } 130 | 131 | fn response_to_byte_stream(res: Self::HttpResponse) -> BoxStream { 132 | let stream = res.err_into(); 133 | 134 | Box::new(stream) 135 | } 136 | 137 | fn request_stream( 138 | &self, 139 | req: Self::HttpRequest, 140 | process: F, 141 | ) -> BoxStream 142 | where 143 | F: 'static + Send + Fn(Self::HttpResponse) -> BoxStream, 144 | { 145 | let stream = req 146 | .err_into() 147 | .map_ok(move |mut res| { 148 | match res.status() { 149 | StatusCode::OK => process(res).right_stream(), 150 | // If the server responded with an error status code, the body 151 | // still needs to be read so an error can be built. This block will 152 | // read the entire body stream, then immediately return an error. 153 | // 154 | _ => res 155 | .body() 156 | .map(|maybe_body| match maybe_body { 157 | Ok(body) => Err(Self::process_error_from_body(body)), 158 | Err(e) => Err(e.into()), 159 | }) 160 | .into_stream() 161 | .left_stream(), 162 | } 163 | }) 164 | .try_flatten_stream(); 165 | 166 | Box::new(stream) 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /ipfs-api-backend-actix/src/error.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use thiserror::Error; 10 | 11 | #[derive(Debug, Error)] 12 | pub enum Error { 13 | #[error("api returned error `{0}`")] 14 | Api(ipfs_api_prelude::ApiError), 15 | 16 | #[error("actix client payload error `{0}`")] 17 | ClientPayload(#[from] awc::error::PayloadError), 18 | 19 | #[error("actix client send request error `{0}`")] 20 | ClientSend(#[from] awc::error::SendRequestError), 21 | 22 | #[error("http error `{0}`")] 23 | Http(#[from] http::Error), 24 | 25 | #[error("ipfs client error `{0}`")] 26 | IpfsClientError(#[from] ipfs_api_prelude::Error), 27 | } 28 | 29 | impl From for Error { 30 | fn from(err: ipfs_api_prelude::ApiError) -> Self { 31 | Error::Api(err) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ipfs-api-backend-actix/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | 8 | //! Connect to an IPFS API using a client implemented with Actix. 9 | //! 10 | //! # Example 11 | //! 12 | //! ```rust 13 | //! use ipfs_api_backend_actix::{IpfsApi, IpfsClient}; 14 | //! use ipfs_api_backend_actix::response::VersionResponse; 15 | //! 16 | //! async fn example() -> Result { 17 | //! let client = IpfsClient::default(); 18 | //! 19 | //! client.version().await 20 | //! } 21 | //! ``` 22 | 23 | extern crate actix_multipart_rfc7578 as multipart; 24 | 25 | mod backend; 26 | mod error; 27 | 28 | pub type IpfsClient = ActixBackend; 29 | pub use crate::{backend::ActixBackend, error::Error}; 30 | pub use ipfs_api_prelude::{ 31 | request::{self, KeyType, Logger, LoggingLevel, ObjectTemplate}, 32 | response, ApiError, BackendWithGlobalOptions, GlobalOptions, IpfsApi, TryFromUri, 33 | }; 34 | pub use multipart::client::multipart::Form; 35 | -------------------------------------------------------------------------------- /ipfs-api-backend-hyper/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ipfs-api-backend-hyper" 3 | description = "Hyper implementation of IPFS HTTP API" 4 | authors = ["Ferris Tseng "] 5 | edition = "2021" 6 | documentation = "https://docs.rs/ipfs-api" 7 | repository = "https://github.com/ferristseng/rust-ipfs-api" 8 | keywords = ["ipfs"] 9 | categories = ["filesystem", "web-programming"] 10 | version = "0.6.0" 11 | readme = "../README.md" 12 | license = "MIT OR Apache-2.0" 13 | 14 | [badges] 15 | github = { repository = "ferristseng/rust-ipfs-api", workflow = "Rust" } 16 | maintenance = { status = "passively-maintained" } 17 | 18 | [features] 19 | with-builder = ["ipfs-api-prelude/with-builder"] 20 | with-hyper-tls = ["hyper-tls"] 21 | with-hyper-rustls = ["hyper-rustls"] 22 | with-send-sync = ["ipfs-api-prelude/with-send-sync"] 23 | 24 | [dependencies] 25 | async-trait = "0.1" 26 | base64 = "0.13" 27 | bytes = "1" 28 | futures = "0.3" 29 | http = "0.2" 30 | hyper = { version = "0.14", features = ["http1", "http2", "client", "tcp"] } 31 | hyper-multipart-rfc7578 = "0.8" 32 | hyper-rustls = { version = "0.23", features = ["rustls-native-certs"], optional = true } 33 | hyper-tls = { version = "0.5", optional = true } 34 | ipfs-api-prelude = { version = "0.6", path = "../ipfs-api-prelude" } 35 | thiserror = "1" 36 | -------------------------------------------------------------------------------- /ipfs-api-backend-hyper/src/error.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use thiserror::Error; 10 | 11 | #[derive(Debug, Error)] 12 | pub enum Error { 13 | #[error("api returned error `{0}`")] 14 | Api(ipfs_api_prelude::ApiError), 15 | 16 | #[error("hyper client error `{0}`")] 17 | Client(#[from] hyper::Error), 18 | 19 | #[error("http error `{0}`")] 20 | Http(#[from] http::Error), 21 | 22 | #[error("ipfs client error `{0}`")] 23 | IpfsClientError(#[from] ipfs_api_prelude::Error), 24 | } 25 | 26 | impl From for Error { 27 | fn from(err: ipfs_api_prelude::ApiError) -> Self { 28 | Error::Api(err) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ipfs-api-backend-hyper/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | 8 | //! Connect to an IPFS API using a client implemented with hyper. 9 | //! 10 | //! # Example 11 | //! 12 | //! ```rust 13 | //! use ipfs_api_backend_hyper::{IpfsApi, IpfsClient}; 14 | //! use ipfs_api_backend_hyper::response::VersionResponse; 15 | //! 16 | //! async fn example() -> Result { 17 | //! let client = IpfsClient::default(); 18 | //! 19 | //! client.version().await 20 | //! } 21 | //! ``` 22 | 23 | extern crate hyper_multipart_rfc7578 as multipart; 24 | 25 | mod backend; 26 | mod error; 27 | 28 | pub type IpfsClient = HyperBackend; 29 | pub use crate::{backend::HyperBackend, error::Error}; 30 | pub use ipfs_api_prelude::{ 31 | request::{self, KeyType, Logger, LoggingLevel, ObjectTemplate}, 32 | response, ApiError, BackendWithGlobalOptions, GlobalOptions, IpfsApi, TryFromUri, 33 | }; 34 | pub use multipart::client::multipart::Form; 35 | -------------------------------------------------------------------------------- /ipfs-api-examples/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ipfs-api-examples" 3 | description = "Examples for IPFS HTTP API clients" 4 | authors = ["Ferris Tseng "] 5 | edition = "2021" 6 | documentation = "https://docs.rs/ipfs-api" 7 | repository = "https://github.com/ferristseng/rust-ipfs-api" 8 | keywords = ["ipfs"] 9 | categories = ["filesystem", "web-programming"] 10 | version = "0.6.0" 11 | readme = "../README.md" 12 | license = "MIT OR Apache-2.0" 13 | 14 | [badges] 15 | github = { repository = "ferristseng/rust-ipfs-api", workflow = "Rust" } 16 | maintenance = { status = "passively-maintained" } 17 | 18 | [features] 19 | default = ["with-hyper"] 20 | with-hyper = ["ipfs-api-backend-hyper", "tokio/macros", "tokio/rt-multi-thread"] 21 | with-hyper-tls = ["with-hyper", "ipfs-api-backend-hyper/with-hyper-tls"] 22 | with-hyper-rustls = ["with-hyper", "ipfs-api-backend-hyper/with-hyper-rustls"] 23 | with-actix = ["ipfs-api-backend-actix", "actix-rt"] 24 | 25 | [dependencies] 26 | actix-rt = { version = "2.6", optional = true } 27 | futures = "0.3" 28 | ipfs-api-backend-actix = { version = "0.7", path = "../ipfs-api-backend-actix", optional = true } 29 | ipfs-api-backend-hyper = { version = "0.6", path = "../ipfs-api-backend-hyper", optional = true } 30 | tar = "0.4" 31 | thiserror = "1" 32 | tokio = { version = "1", features = ["time"] } 33 | tokio-stream = { version = "0.1", features = ["time"] } 34 | tracing-subscriber = { version = "0.3", features = ["fmt"] } 35 | -------------------------------------------------------------------------------- /ipfs-api-examples/examples/add_file.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use ipfs_api_examples::ipfs_api::{IpfsApi, IpfsClient}; 10 | use std::fs::File; 11 | 12 | // Creates an Ipfs client, and adds this source file to Ipfs. 13 | // 14 | #[ipfs_api_examples::main] 15 | async fn main() { 16 | tracing_subscriber::fmt::init(); 17 | 18 | eprintln!("note: this must be run in the root of the project repository"); 19 | eprintln!("connecting to localhost:5001..."); 20 | 21 | let client = IpfsClient::default(); 22 | let file = File::open(file!()).expect("could not read source file"); 23 | 24 | match client.add(file).await { 25 | Ok(file) => eprintln!("added file: {:?}", file), 26 | Err(e) => eprintln!("error adding file: {}", e), 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ipfs-api-examples/examples/add_file_piped_from_command.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use ipfs_api_examples::ipfs_api::{IpfsApi, IpfsClient}; 10 | use std::process::{Command, Stdio}; 11 | 12 | // Creates an Ipfs client, and pipes the result of a command into Ipfs. 13 | // 14 | #[ipfs_api_examples::main] 15 | async fn main() { 16 | tracing_subscriber::fmt::init(); 17 | 18 | eprintln!("note: this must be run in the root of the project repository"); 19 | eprintln!("connecting to localhost:5001..."); 20 | 21 | let client = IpfsClient::default(); 22 | 23 | let mut output = Command::new("cat") 24 | .arg("README.md") 25 | .stdout(Stdio::piped()) 26 | .spawn() 27 | .expect("expected to run `cat`"); 28 | 29 | match client.add(output.stdout.take().unwrap()).await { 30 | Ok(file) => eprintln!("added file: {:?}", file), 31 | Err(e) => eprintln!("error adding file: {}", e), 32 | } 33 | 34 | let result = output.wait().expect("expected `cat` to finish"); 35 | 36 | eprintln!("`cat` exited with {:?}", result.code()); 37 | } 38 | -------------------------------------------------------------------------------- /ipfs-api-examples/examples/add_tar.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use futures::TryStreamExt; 10 | use ipfs_api_examples::ipfs_api::{IpfsApi, IpfsClient}; 11 | use std::io::Cursor; 12 | use tar::Builder; 13 | 14 | // Creates an Ipfs client, and adds this source file to Ipfs. 15 | // 16 | #[ipfs_api_examples::main] 17 | async fn main() { 18 | tracing_subscriber::fmt::init(); 19 | 20 | eprintln!("note: this must be run in the root of the project repository"); 21 | eprintln!("connecting to localhost:5001..."); 22 | 23 | let client = IpfsClient::default(); 24 | 25 | // Create a in-memory tar file with this source file as its contents. 26 | // 27 | let mut buf = Vec::new(); 28 | { 29 | let mut builder = Builder::new(&mut buf); 30 | 31 | builder 32 | .append_path(file!()) 33 | .expect("failed to create tar file"); 34 | builder.finish().expect("failed to create tar file"); 35 | } 36 | let cursor = Cursor::new(buf); 37 | 38 | // Write in-memory tar file to IPFS. 39 | // 40 | let file = match client.tar_add(cursor).await { 41 | Ok(file) => { 42 | eprintln!("added tar file: {:?}", file); 43 | eprintln!(); 44 | 45 | file 46 | } 47 | Err(e) => { 48 | eprintln!("error writing tar file: {}", e); 49 | 50 | return; 51 | } 52 | }; 53 | 54 | // Read tar file from IPFS. 55 | // 56 | match client 57 | .tar_cat(&file.hash[..]) 58 | .map_ok(|chunk| chunk.to_vec()) 59 | .try_concat() 60 | .await 61 | { 62 | Ok(tar) => { 63 | println!("{}", String::from_utf8_lossy(&tar[..])); 64 | } 65 | Err(e) => { 66 | eprintln!("error reading tar file: {}", e); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /ipfs-api-examples/examples/app_error_enum.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | 8 | //! Demonstrates how to define an application error enum that has an ipfs_api::Error as possibility. 9 | 10 | use ipfs_api_examples::ipfs_api; 11 | use ipfs_api_examples::ipfs_api::response::VersionResponse; 12 | use ipfs_api_examples::ipfs_api::{IpfsApi, IpfsClient}; 13 | 14 | /// An error type that is either an IPFS client error, or some other error. 15 | #[derive(Debug, thiserror::Error)] 16 | enum ApplicationError { 17 | #[error("IPFS error: {0}")] 18 | Ipfs(#[from] ipfs_api::Error), 19 | 20 | #[error("{0}")] 21 | Message(String), 22 | } 23 | 24 | /// Similar to get_version example, except implementation is in a function called by main rather 25 | /// than in main itself, and the callee, use_client, returns Result with a custom error type. 26 | #[ipfs_api_examples::main] 27 | async fn main() { 28 | tracing_subscriber::fmt::init(); 29 | 30 | let client = IpfsClient::default(); 31 | 32 | // Get and print version, using client directly 33 | if let Err(e) = use_api(&client).await { 34 | eprintln!("{:?}", e); 35 | } 36 | 37 | // Get and print version, using client by its trait IpfsApi 38 | if let Err(e) = use_client(&client).await { 39 | eprintln!("{:?}", e); 40 | } 41 | } 42 | 43 | fn print_version(version: VersionResponse) -> Result<(), ApplicationError> { 44 | if version.version.starts_with("0.0") { 45 | Err(ApplicationError::Message(format!( 46 | "Version {} is very old", 47 | version.version 48 | ))) 49 | } else { 50 | println!("Version: {}", version.version); 51 | Ok(()) 52 | } 53 | } 54 | 55 | async fn use_api>(client: &A) -> Result<(), ApplicationError> { 56 | let version = client.version().await?; 57 | 58 | print_version(version) 59 | } 60 | 61 | async fn use_client(client: &IpfsClient) -> Result<(), ApplicationError> { 62 | let version = client.version().await?; 63 | 64 | print_version(version) 65 | } 66 | -------------------------------------------------------------------------------- /ipfs-api-examples/examples/basic_auth.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | 8 | use std::env; 9 | 10 | use ipfs_api_examples::ipfs_api::{IpfsApi, IpfsClient, TryFromUri}; 11 | 12 | fn expect_env(key: &str) -> String { 13 | env::var(key).expect(key) 14 | } 15 | 16 | /// Creates an IPFS client, and sets credentials to use. 17 | #[ipfs_api_examples::main] 18 | async fn main() { 19 | let ipfs_api_url = expect_env("IPFS_API_URL"); 20 | let ipfs_api_username = expect_env("IPFS_API_USERNAME"); 21 | let ipfs_api_password = expect_env("IPFS_API_PASSWORD"); 22 | 23 | println!("Connecting to {} as {}...", ipfs_api_url, ipfs_api_username); 24 | 25 | let client = IpfsClient::from_str(&ipfs_api_url) 26 | .unwrap() 27 | .with_credentials(ipfs_api_username, ipfs_api_password); 28 | 29 | match client.version().await { 30 | Ok(version) => println!("version: {}", version.version), 31 | Err(e) => eprintln!("error getting version: {}", e), 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ipfs-api-examples/examples/bootstrap_default.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use ipfs_api_examples::ipfs_api::{IpfsApi, IpfsClient}; 10 | 11 | // Lists clients in bootstrap list, then adds the default list, then removes 12 | // them, and readds them. 13 | // 14 | #[ipfs_api_examples::main] 15 | async fn main() { 16 | tracing_subscriber::fmt::init(); 17 | 18 | eprintln!("connecting to localhost:5001..."); 19 | 20 | let client = IpfsClient::default(); 21 | 22 | match client.bootstrap_list().await { 23 | Ok(bootstrap) => { 24 | eprintln!("current bootstrap peers:"); 25 | for peer in bootstrap.peers { 26 | eprintln!(" {}", peer); 27 | } 28 | eprintln!(); 29 | } 30 | Err(e) => { 31 | eprintln!("error getting list of bootstrap peers: {}", e); 32 | return; 33 | } 34 | } 35 | 36 | match client.bootstrap_rm_all().await { 37 | Ok(drop) => { 38 | eprintln!("dropped:"); 39 | for peer in drop.peers { 40 | eprintln!(" {}", peer); 41 | } 42 | eprintln!(); 43 | } 44 | Err(e) => { 45 | eprintln!("error dropping bootstrap peers: {}", e); 46 | return; 47 | } 48 | } 49 | 50 | match client.bootstrap_add_default().await { 51 | Ok(add) => { 52 | eprintln!("added:"); 53 | for peer in add.peers { 54 | eprintln!(" {}", peer); 55 | } 56 | eprintln!(); 57 | } 58 | Err(e) => { 59 | eprintln!("error adding default peers: {}", e); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /ipfs-api-examples/examples/cat.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use futures::TryStreamExt; 10 | use ipfs_api_examples::ipfs_api::{IpfsApi, IpfsClient}; 11 | use std::fs::File; 12 | 13 | // Creates an Ipfs client, uploads a file, and reads it. 14 | // 15 | #[ipfs_api_examples::main] 16 | async fn main() -> Result<(), &'static str> { 17 | tracing_subscriber::fmt::init(); 18 | 19 | eprintln!("connecting to localhost:5001..."); 20 | 21 | let client = IpfsClient::default(); 22 | 23 | eprintln!("adding this example source file to IPFS..."); 24 | 25 | let file = File::open(file!()).expect("could not read source file"); 26 | let added_file = client 27 | .add(file) 28 | .await 29 | .map_err(|_| "error adding source file")?; 30 | 31 | let offset = 1065; 32 | let length = 390; 33 | 34 | eprintln!("cat {} bytes from {}...", length, offset); 35 | 36 | let section = client 37 | .cat_range(&added_file.hash[..], offset, length) 38 | .map_ok(|chunk| chunk.to_vec()) 39 | .try_concat() 40 | .await 41 | .map_err(|_| "error reading file from offset")?; 42 | eprintln!("---------------------------------------"); 43 | eprintln!("{}", String::from_utf8_lossy(§ion[..])); 44 | eprintln!("---------------------------------------"); 45 | 46 | eprintln!("reading full file..."); 47 | 48 | let all = client 49 | .cat(&added_file.hash[..]) 50 | .map_ok(|chunk| chunk.to_vec()) 51 | .try_concat() 52 | .await 53 | .map_err(|_| "error reading full file")?; 54 | eprintln!("---------------------------------------"); 55 | eprintln!("{}", String::from_utf8_lossy(&all[..])); 56 | eprintln!("---------------------------------------"); 57 | 58 | Ok(()) 59 | } 60 | -------------------------------------------------------------------------------- /ipfs-api-examples/examples/check_file_local.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use futures::StreamExt; 10 | use ipfs_api_examples::ipfs_api::{ 11 | request::Ls, response::LsResponse, ApiError, BackendWithGlobalOptions, Error as IpfsError, 12 | GlobalOptions, IpfsApi, IpfsClient, 13 | }; 14 | use std::process::exit; 15 | 16 | // Creates an Ipfs client, and recursively checks whether argv[1] is cached on the local node. 17 | // 18 | #[ipfs_api_examples::main] 19 | async fn main() { 20 | tracing_subscriber::fmt::init(); 21 | 22 | eprintln!("note: this must be run in the root of the project repository"); 23 | eprintln!("connecting to localhost:5001..."); 24 | 25 | let client = BackendWithGlobalOptions::new( 26 | IpfsClient::default(), 27 | GlobalOptions::builder() 28 | .offline(true) // This is the entire trick! 29 | .build(), 30 | ); 31 | // See also: https://discuss.ipfs.io/t/how-to-check-if-an-ipfs-object-is-on-your-local-node/1250/2 32 | // Note that if you have the file in mfs (ipfs files ...), ipfs files stat --with-local is likely faster 33 | 34 | let start_cid = std::env::args() 35 | .nth(1) 36 | .unwrap_or_else(|| "QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn".into()); 37 | let mut cids = vec![start_cid]; 38 | 39 | while let Some(cid) = cids.pop() { 40 | println!("Checking {}", cid); 41 | let mut ls = client.ls_with_options( 42 | Ls::builder() 43 | .path(&cid) 44 | .resolve_type(false) 45 | .size(false) 46 | .build(), 47 | ); 48 | while let Some(ls_chunk) = ls.next().await { 49 | match ls_chunk { 50 | Ok(LsResponse { objects, .. }) => { 51 | for object in objects { 52 | for file in object.links { 53 | cids.push(file.hash) 54 | } 55 | } 56 | } 57 | Err(IpfsError::Api(ApiError { message, .. })) => { 58 | // A better implementation would check for the semantic equivalent of "mergkledag: not found" 59 | // I don't match on error messages by principle 60 | println!("{} may be not local: {}", cid, message); 61 | exit(1); 62 | } 63 | Err(e) => { 64 | println!("Error while walking: {:?}", e); 65 | exit(-1); 66 | } 67 | } 68 | } 69 | } 70 | println!("All local"); 71 | } 72 | -------------------------------------------------------------------------------- /ipfs-api-examples/examples/config.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use ipfs_api_examples::ipfs_api::{IpfsApi, IpfsClient}; 10 | 11 | // Creates an Ipfs client, read & set config values. 12 | // 13 | #[ipfs_api_examples::main] 14 | async fn main() { 15 | tracing_subscriber::fmt::init(); 16 | 17 | eprintln!("note: this must be run in the root of the project repository"); 18 | eprintln!("connecting to localhost:5001..."); 19 | 20 | let client = IpfsClient::default(); 21 | 22 | //read a string 23 | let response = client 24 | .config_get_string("Identity.PeerID") 25 | .await 26 | .expect("Config read failed"); 27 | 28 | println!("Config: {}={}", response.key, response.value); 29 | 30 | //read a bool 31 | let response = client 32 | .config_get_bool("Datastore.HashOnRead") 33 | .await 34 | .expect("Config read failed"); 35 | 36 | println!("Config: {}={}", response.key, response.value); 37 | 38 | //read a stringified json 39 | let response = client 40 | .config_get_json("Mounts") 41 | .await 42 | .expect("Config read failed"); 43 | 44 | println!("Config: {}={}", response.key, response.value); 45 | 46 | //set a string value 47 | let response = client 48 | .config_set_string("Routing.Type", "dht") 49 | .await 50 | .expect("Config write failed"); 51 | 52 | println!("Config: {}={}", response.key, response.value); 53 | 54 | //set a boolean value 55 | let response = client 56 | .config_set_bool("Pubsub.DisableSigning", false) 57 | .await 58 | .expect("Config write failed"); 59 | 60 | println!("Config: {}={}", response.key, response.value); 61 | 62 | //set a json value 63 | let response = client 64 | .config_set_json("Discovery", r#"{"MDNS":{"Enabled":true,"Interval":10}}"#) 65 | .await 66 | .expect("Config write failed"); 67 | 68 | println!("Config: {}={}", response.key, response.value); 69 | } 70 | -------------------------------------------------------------------------------- /ipfs-api-examples/examples/dag.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use futures::TryStreamExt; 10 | use ipfs_api_examples::ipfs_api::{IpfsApi, IpfsClient}; 11 | use std::io::Cursor; 12 | 13 | // Creates an Ipfs client, and adds this dag object to Ipfs then fetch it back. 14 | // 15 | #[ipfs_api_examples::main] 16 | async fn main() { 17 | tracing_subscriber::fmt::init(); 18 | 19 | eprintln!("note: this must be run in the root of the project repository"); 20 | eprintln!("connecting to localhost:5001..."); 21 | 22 | let client = IpfsClient::default(); 23 | 24 | let dag_node = Cursor::new(r#"{"hello":"world"}"#); 25 | 26 | let response = client 27 | .dag_put(dag_node) 28 | .await 29 | .expect("error adding dag node"); 30 | 31 | let cid = response.cid.cid_string; 32 | 33 | match client 34 | .dag_get(&cid) 35 | .map_ok(|chunk| chunk.to_vec()) 36 | .try_concat() 37 | .await 38 | { 39 | Ok(bytes) => { 40 | println!("{}", String::from_utf8_lossy(&bytes[..])); 41 | } 42 | Err(e) => { 43 | eprintln!("error reading dag node: {}", e); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ipfs-api-examples/examples/default_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "Identity": { 3 | "PeerID": "QmVRF8ZnT1ootg5vSrzS4ws8W8NwzF5q5MUCzfNK6ZmYeH" 4 | }, 5 | "Datastore": { 6 | "StorageMax": "10GB", 7 | "StorageGCWatermark": 90, 8 | "GCPeriod": "1h", 9 | "Spec": { 10 | "mounts": [ 11 | { 12 | "child": { 13 | "path": "blocks", 14 | "shardFunc": "/repo/flatfs/shard/v1/next-to-last/2", 15 | "sync": true, 16 | "type": "flatfs" 17 | }, 18 | "mountpoint": "/blocks", 19 | "prefix": "flatfs.datastore", 20 | "type": "measure" 21 | }, 22 | { 23 | "child": { 24 | "compression": "none", 25 | "path": "datastore", 26 | "type": "levelds" 27 | }, 28 | "mountpoint": "/", 29 | "prefix": "leveldb.datastore", 30 | "type": "measure" 31 | } 32 | ], 33 | "type": "mount" 34 | }, 35 | "HashOnRead": false, 36 | "BloomFilterSize": 0 37 | }, 38 | "Addresses": { 39 | "Swarm": [ 40 | "/ip4/0.0.0.0/tcp/4001", 41 | "/ip6/::/tcp/4001" 42 | ], 43 | "Announce": [], 44 | "NoAnnounce": [], 45 | "API": "/ip4/127.0.0.1/tcp/5001", 46 | "Gateway": "/ip4/127.0.0.1/tcp/8080" 47 | }, 48 | "Mounts": { 49 | "IPFS": "/ipfs", 50 | "IPNS": "/ipns", 51 | "FuseAllowOther": false 52 | }, 53 | "Discovery": { 54 | "MDNS": { 55 | "Enabled": true, 56 | "Interval": 10 57 | } 58 | }, 59 | "Ipns": { 60 | "RepublishPeriod": "", 61 | "RecordLifetime": "", 62 | "ResolveCacheSize": 128 63 | }, 64 | "Bootstrap": [ 65 | "/dnsaddr/bootstrap.libp2p.io/ipfs/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN", 66 | "/dnsaddr/bootstrap.libp2p.io/ipfs/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa", 67 | "/dnsaddr/bootstrap.libp2p.io/ipfs/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb", 68 | "/dnsaddr/bootstrap.libp2p.io/ipfs/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt", 69 | "/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", 70 | "/ip4/104.236.179.241/tcp/4001/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM", 71 | "/ip4/128.199.219.111/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu", 72 | "/ip4/104.236.76.40/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64", 73 | "/ip4/178.62.158.247/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd", 74 | "/ip6/2604:a880:1:20::203:d001/tcp/4001/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM", 75 | "/ip6/2400:6180:0:d0::151:6001/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu", 76 | "/ip6/2604:a880:800:10::4a:5001/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64", 77 | "/ip6/2a03:b0c0:0:1010::23:1001/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd" 78 | ], 79 | "Gateway": { 80 | "HTTPHeaders": { 81 | "Access-Control-Allow-Headers": [ 82 | "X-Requested-With", 83 | "Range" 84 | ], 85 | "Access-Control-Allow-Methods": [ 86 | "GET" 87 | ], 88 | "Access-Control-Allow-Origin": [ 89 | "*" 90 | ] 91 | }, 92 | "RootRedirect": "", 93 | "Writable": false, 94 | "PathPrefixes": [] 95 | }, 96 | "API": { 97 | "HTTPHeaders": null 98 | }, 99 | "Swarm": { 100 | "AddrFilters": null, 101 | "DisableBandwidthMetrics": false, 102 | "DisableNatPortMap": false, 103 | "DisableRelay": false, 104 | "EnableRelayHop": false, 105 | "ConnMgr": { 106 | "Type": "basic", 107 | "LowWater": 600, 108 | "HighWater": 900, 109 | "GracePeriod": "20s" 110 | } 111 | }, 112 | "Reprovider": { 113 | "Interval": "12h", 114 | "Strategy": "all" 115 | }, 116 | "Experimental": { 117 | "FilestoreEnabled": false, 118 | "ShardingEnabled": false, 119 | "Libp2pStreamMounting": false 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /ipfs-api-examples/examples/dns.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use ipfs_api_examples::ipfs_api::{IpfsApi, IpfsClient}; 10 | 11 | // Creates an Ipfs client, resolves ipfs.io, and lists the contents of it. 12 | // 13 | #[ipfs_api_examples::main] 14 | async fn main() { 15 | tracing_subscriber::fmt::init(); 16 | 17 | eprintln!("connecting to localhost:5001..."); 18 | 19 | let client = IpfsClient::default(); 20 | 21 | let dns = match client.dns("ipfs.io", true).await { 22 | Ok(dns) => { 23 | eprintln!("dns resolves to ({})", &dns.path); 24 | eprintln!(); 25 | 26 | dns 27 | } 28 | Err(e) => { 29 | eprintln!("error resolving dns: {}", e); 30 | return; 31 | } 32 | }; 33 | 34 | match client.object_get(&dns.path[..]).await { 35 | Ok(contents) => { 36 | eprintln!("found contents:"); 37 | for link in contents.links.iter() { 38 | eprintln!("[{}] ({} bytes)", link.name, link.size); 39 | } 40 | } 41 | Err(e) => eprintln!("error listing path: {}", e), 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ipfs-api-examples/examples/get_commands.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use ipfs_api_examples::ipfs_api::{response, IpfsApi, IpfsClient}; 10 | 11 | fn print_recursive(indent: usize, cmd: &response::CommandsResponse) { 12 | let cmd_indent = " ".repeat(indent * 4); 13 | let opt_indent = " ".repeat((indent + 1) * 4); 14 | 15 | eprintln!("{}[{}]", cmd_indent, cmd.name); 16 | 17 | if !cmd.options.is_empty() { 18 | eprintln!("{}* options:", cmd_indent); 19 | for options in cmd.options.iter() { 20 | eprintln!("{}{}", opt_indent, &options.names[..].join(", ")); 21 | } 22 | } 23 | 24 | if !cmd.subcommands.is_empty() { 25 | eprintln!("{}- subcommands:", cmd_indent); 26 | for subcommand in cmd.subcommands.iter() { 27 | print_recursive(indent + 1, subcommand); 28 | } 29 | } 30 | } 31 | 32 | // Creates an Ipfs client, and gets a list of available commands from the 33 | // Ipfs server. 34 | // 35 | #[ipfs_api_examples::main] 36 | async fn main() { 37 | tracing_subscriber::fmt::init(); 38 | 39 | eprintln!("connecting to localhost:5001..."); 40 | 41 | let client = IpfsClient::default(); 42 | 43 | match client.commands().await { 44 | Ok(commands) => print_recursive(0, &commands), 45 | Err(e) => eprintln!("error getting commands: {}", e), 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ipfs-api-examples/examples/get_stats.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use ipfs_api_examples::ipfs_api::{IpfsApi, IpfsClient}; 10 | 11 | // Creates an Ipfs client, and gets some stats about the Ipfs server. 12 | // 13 | #[ipfs_api_examples::main] 14 | async fn main() { 15 | tracing_subscriber::fmt::init(); 16 | 17 | eprintln!("connecting to localhost:5001..."); 18 | 19 | let client = IpfsClient::default(); 20 | 21 | match client.stats_bitswap().await { 22 | Ok(bitswap_stats) => { 23 | eprintln!("bitswap stats:"); 24 | eprintln!(" blocks recv: {}", bitswap_stats.blocks_received); 25 | eprintln!(" data recv: {}", bitswap_stats.data_received); 26 | eprintln!(" blocks sent: {}", bitswap_stats.blocks_sent); 27 | eprintln!(" data sent: {}", bitswap_stats.data_sent); 28 | eprintln!( 29 | " peers: {}", 30 | bitswap_stats.peers.join("\n ") 31 | ); 32 | eprintln!( 33 | " wantlist: {}", 34 | bitswap_stats.wantlist.join("\n ") 35 | ); 36 | eprintln!(); 37 | } 38 | Err(e) => eprintln!("error getting bitswap stats: {}", e), 39 | } 40 | 41 | match client.stats_bw().await { 42 | Ok(bw_stats) => { 43 | eprintln!("bandwidth stats:"); 44 | eprintln!(" total in: {}", bw_stats.total_in); 45 | eprintln!(" total out: {}", bw_stats.total_out); 46 | eprintln!(" rate in: {}", bw_stats.rate_in); 47 | eprintln!(" rate out: {}", bw_stats.rate_out); 48 | eprintln!(); 49 | } 50 | Err(e) => eprintln!("error getting bandwidth stats: {}", e), 51 | } 52 | 53 | match client.stats_repo().await { 54 | Ok(repo_stats) => { 55 | eprintln!("repo stats:"); 56 | eprintln!(" num objs: {}", repo_stats.num_objects); 57 | eprintln!(" repo size: {}", repo_stats.repo_size); 58 | eprintln!(" repo path: {}", repo_stats.repo_path); 59 | eprintln!(" version : {}", repo_stats.version); 60 | } 61 | Err(e) => eprintln!("error getting repo stats: {}", e), 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /ipfs-api-examples/examples/get_swarm.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use ipfs_api_examples::ipfs_api::{IpfsApi, IpfsClient}; 10 | 11 | // Creates an Ipfs client, and gets information about your local address, and 12 | // connected peers. 13 | // 14 | #[ipfs_api_examples::main] 15 | async fn main() { 16 | tracing_subscriber::fmt::init(); 17 | 18 | eprintln!("connecting to localhost:5001..."); 19 | 20 | let client = IpfsClient::default(); 21 | 22 | match client.swarm_addrs_local().await { 23 | Ok(local) => { 24 | eprintln!("your addrs:"); 25 | for addr in local.strings { 26 | eprintln!(" {}", addr); 27 | } 28 | eprintln!(); 29 | } 30 | Err(e) => eprintln!("error getting local swarm addresses: {}", e), 31 | } 32 | 33 | match client.swarm_peers().await { 34 | Ok(connected) => { 35 | eprintln!("connected:"); 36 | for peer in connected.peers { 37 | let streams: Vec<&str> = peer.streams.iter().map(|s| &s.protocol[..]).collect(); 38 | eprintln!(" addr: {}", peer.addr); 39 | eprintln!(" peer: {}", peer.peer); 40 | eprintln!(" latency: {}", peer.latency); 41 | eprintln!(" muxer: {}", peer.muxer); 42 | eprintln!(" streams: {}", streams.join(", ")); 43 | eprintln!(); 44 | } 45 | } 46 | Err(e) => eprintln!("error getting swarm peers: {}", e), 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ipfs-api-examples/examples/get_version.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use ipfs_api_examples::ipfs_api::{IpfsApi, IpfsClient}; 10 | 11 | // Creates an Ipfs client, and gets the version of the Ipfs server. 12 | // 13 | #[ipfs_api_examples::main] 14 | async fn main() { 15 | tracing_subscriber::fmt::init(); 16 | 17 | eprintln!("connecting to localhost:5001..."); 18 | 19 | let client = IpfsClient::default(); 20 | 21 | match client.version().await { 22 | Ok(version) => println!("version: {}", version.version), 23 | Err(e) => eprintln!("error getting version: {}", e), 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ipfs-api-examples/examples/log_tail.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2019 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use futures::{future, TryStreamExt}; 10 | use ipfs_api_examples::ipfs_api::{IpfsApi, IpfsClient}; 11 | 12 | // Tails the log of IPFS. 13 | // 14 | #[ipfs_api_examples::main] 15 | async fn main() { 16 | tracing_subscriber::fmt::init(); 17 | 18 | eprintln!("connecting to localhost:5001..."); 19 | 20 | let client = IpfsClient::default(); 21 | 22 | if let Err(e) = client 23 | .log_tail() 24 | .try_for_each(|line| { 25 | println!("{}", line); 26 | 27 | future::ok(()) 28 | }) 29 | .await 30 | { 31 | eprintln!("error getting tail of log: {}", e); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ipfs-api-examples/examples/mfs.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use ipfs_api_examples::ipfs_api::{response, IpfsApi, IpfsClient}; 10 | use std::fs::File; 11 | 12 | fn print_stat(stat: response::FilesStatResponse) { 13 | eprintln!(" type : {}", stat.typ); 14 | eprintln!(" hash : {}", stat.hash); 15 | eprintln!(" size : {}", stat.size); 16 | eprintln!(" cum. size: {}", stat.cumulative_size); 17 | eprintln!(" blocks : {}", stat.blocks); 18 | eprintln!(); 19 | } 20 | 21 | // Creates an Ipfs client, and makes some calls to the Mfs Api. 22 | // 23 | #[ipfs_api_examples::main] 24 | async fn main() { 25 | tracing_subscriber::fmt::init(); 26 | 27 | eprintln!("note: this must be run in the root of the project repository"); 28 | eprintln!("connecting to localhost:5001..."); 29 | 30 | let client = IpfsClient::default(); 31 | 32 | eprintln!("making /test..."); 33 | eprintln!(); 34 | 35 | if let Err(e) = client.files_mkdir("/test", false).await { 36 | eprintln!("error making /test: {}", e); 37 | return; 38 | } 39 | 40 | eprintln!("making dirs /test/does/not/exist/yet..."); 41 | eprintln!(); 42 | 43 | if let Err(e) = client.files_mkdir("/test/does/not/exist/yet", true).await { 44 | eprintln!("error making /test/does/not/exist/yet: {}", e); 45 | return; 46 | } 47 | 48 | eprintln!("getting status of /test/does..."); 49 | eprintln!(); 50 | 51 | match client.files_stat("/test/does").await { 52 | Ok(stat) => print_stat(stat), 53 | Err(e) => { 54 | eprintln!("error getting status of /test/does: {}", e); 55 | return; 56 | } 57 | } 58 | 59 | eprintln!("writing source file to /test/mfs.rs"); 60 | eprintln!(); 61 | 62 | let src = File::open(file!()).expect("could not read source file"); 63 | 64 | if let Err(e) = client.files_write("/test/mfs.rs", true, true, src).await { 65 | eprintln!("error writing source file /test/mfs.rs: {}", e); 66 | return; 67 | } 68 | 69 | eprintln!("getting status of /test/mfs.rs..."); 70 | eprintln!(); 71 | 72 | match client.files_stat("/test/mfs.rs").await { 73 | Ok(stat) => print_stat(stat), 74 | Err(e) => { 75 | eprintln!("error getting status of /test/mfs.rs: {}", e); 76 | return; 77 | } 78 | } 79 | 80 | eprintln!("removing /test..."); 81 | eprintln!(); 82 | 83 | if let Err(e) = client.files_rm("/test", true).await { 84 | eprintln!("error removing /test: {}", e); 85 | } 86 | 87 | eprintln!("done!"); 88 | } 89 | -------------------------------------------------------------------------------- /ipfs-api-examples/examples/ping_peer.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use futures::{future, TryStreamExt}; 10 | use ipfs_api_examples::ipfs_api::{response::PingResponse, IpfsApi, IpfsClient}; 11 | 12 | // Creates an Ipfs client, discovers a connected peer, and pings it using the 13 | // streaming Api, and by collecting it into a collection. 14 | // 15 | #[ipfs_api_examples::main] 16 | async fn main() { 17 | tracing_subscriber::fmt::init(); 18 | 19 | eprintln!("connecting to localhost:5001..."); 20 | 21 | let client = IpfsClient::default(); 22 | 23 | eprintln!(); 24 | eprintln!("discovering connected peers..."); 25 | 26 | let peer = match client.swarm_peers().await { 27 | Ok(connected) => connected 28 | .peers 29 | .into_iter() 30 | .next() 31 | .expect("expected at least one peer"), 32 | Err(e) => { 33 | eprintln!("error getting connected peers: {}", e); 34 | return; 35 | } 36 | }; 37 | 38 | eprintln!(); 39 | eprintln!("discovered peer ({})", peer.peer); 40 | eprintln!(); 41 | eprintln!("streaming 10 pings..."); 42 | 43 | if let Err(e) = client 44 | .ping(&peer.peer[..], Some(10)) 45 | .try_for_each(|ping| { 46 | eprintln!("{:?}", ping); 47 | 48 | future::ok(()) 49 | }) 50 | .await 51 | { 52 | eprintln!("error streaming pings: {}", e); 53 | } 54 | 55 | eprintln!(); 56 | eprintln!("gathering 15 pings..."); 57 | 58 | match client 59 | .ping(&peer.peer[..], Some(15)) 60 | .try_collect::>() 61 | .await 62 | { 63 | Ok(pings) => { 64 | for ping in pings.iter() { 65 | eprintln!("got response ({:?}) at ({})...", ping.text, ping.time); 66 | } 67 | } 68 | Err(e) => eprintln!("error collecting pings: {}", e), 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /ipfs-api-examples/examples/pubsub.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use futures::{future, select, FutureExt, StreamExt, TryStreamExt}; 10 | use ipfs_api_examples::ipfs_api::{IpfsApi, IpfsClient}; 11 | use std::{io::Cursor, time::Duration}; 12 | use tokio::time; 13 | use tokio_stream::wrappers::IntervalStream; 14 | 15 | static TOPIC: &str = "test"; 16 | 17 | // Creates an Ipfs client, and simultaneously publishes and reads from a pubsub 18 | // topic. 19 | // 20 | #[ipfs_api_examples::main] 21 | async fn main() { 22 | tracing_subscriber::fmt::init(); 23 | 24 | eprintln!("note: ipfs must be run with pubsub enable in config"); 25 | 26 | let publish_client = IpfsClient::default(); 27 | 28 | // This block will execute a repeating function that sends 29 | // a message to the "test" topic. 30 | // 31 | let interval = time::interval(Duration::from_secs(1)); 32 | let mut publish = IntervalStream::new(interval) 33 | .then(|_| future::ok(())) // Coerce the stream into a TryStream 34 | .try_for_each(|_| { 35 | eprintln!(); 36 | eprintln!("publishing message..."); 37 | 38 | publish_client 39 | .pubsub_pub(TOPIC, Cursor::new("Hello World!")) 40 | .boxed_local() 41 | }) 42 | .boxed_local() 43 | .fuse(); 44 | 45 | // This block will execute a future that subscribes to a topic, 46 | // and reads any incoming messages. 47 | // 48 | let mut subscribe = { 49 | let client = IpfsClient::default(); 50 | 51 | client 52 | .pubsub_sub(TOPIC) 53 | .take(5) 54 | .try_for_each(|msg| { 55 | eprintln!(); 56 | eprintln!("received ({:?})", msg); 57 | 58 | future::ok(()) 59 | }) 60 | .fuse() 61 | }; 62 | 63 | eprintln!(); 64 | eprintln!("publish messages to ({})...", TOPIC); 65 | eprintln!("waiting for messages from ({})...", TOPIC); 66 | 67 | select! { 68 | res = subscribe => match res { 69 | Ok(_) => eprintln!("done reading messages..."), 70 | Err(e) => eprintln!("error reading messages: {}", e) 71 | }, 72 | res = publish => if let Err(e) = res { 73 | eprintln!("error publishing messages: {}", e); 74 | }, 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /ipfs-api-examples/examples/replace_config.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use ipfs_api_examples::ipfs_api::{IpfsApi, IpfsClient}; 10 | use std::io::Cursor; 11 | 12 | // Creates an Ipfs client, and replaces the config file with the default one. 13 | // 14 | #[ipfs_api_examples::main] 15 | async fn main() { 16 | tracing_subscriber::fmt::init(); 17 | 18 | eprintln!("note: this must be run in the root of the project repository"); 19 | eprintln!("connecting to localhost:5001..."); 20 | 21 | let client = IpfsClient::default(); 22 | let default_config = include_str!("default_config.json"); 23 | 24 | match client.config_replace(Cursor::new(default_config)).await { 25 | Ok(_) => eprintln!("replaced config file"), 26 | Err(e) => eprintln!("error replacing config file: {}", e), 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ipfs-api-examples/examples/resolve_name.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use ipfs_api_examples::ipfs_api::{IpfsApi, IpfsClient}; 10 | 11 | const IPFS_IPNS: &str = "/ipns/ipfs.io"; 12 | 13 | // Creates an Ipfs client, and resolves the Ipfs domain name, and 14 | // publishes a path to Ipns. 15 | // 16 | #[ipfs_api_examples::main] 17 | async fn main() { 18 | tracing_subscriber::fmt::init(); 19 | 20 | eprintln!("connecting to localhost:5001..."); 21 | 22 | let client = IpfsClient::default(); 23 | 24 | match client.name_resolve(Some(IPFS_IPNS), true, false).await { 25 | Ok(resolved) => eprintln!("{} resolves to: {}", IPFS_IPNS, &resolved.path), 26 | Err(e) => { 27 | eprintln!("error resolving {}: {}", IPFS_IPNS, e); 28 | return; 29 | } 30 | } 31 | 32 | let publish = match client.name_publish(IPFS_IPNS, true, None, None, None).await { 33 | Ok(publish) => { 34 | eprintln!("published {} to: /ipns/{}", IPFS_IPNS, &publish.name); 35 | publish 36 | } 37 | Err(e) => { 38 | eprintln!("error publishing name: {}", e); 39 | return; 40 | } 41 | }; 42 | 43 | match client.name_resolve(Some(&publish.name), true, false).await { 44 | Ok(resolved) => { 45 | eprintln!("/ipns/{} resolves to: {}", &publish.name, &resolved.path); 46 | } 47 | Err(e) => { 48 | eprintln!("error resolving name: {}", e); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /ipfs-api-examples/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | #[cfg(feature = "with-actix")] 10 | pub use actix_rt::main; 11 | 12 | #[cfg(feature = "with-actix")] 13 | pub use ipfs_api_backend_actix as ipfs_api; 14 | 15 | #[cfg(feature = "with-hyper")] 16 | pub use tokio::main; 17 | 18 | #[cfg(feature = "with-hyper")] 19 | pub use ipfs_api_backend_hyper as ipfs_api; 20 | -------------------------------------------------------------------------------- /ipfs-api-prelude/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ipfs-api-prelude" 3 | description = "Shared code for IPFS HTTP API clients" 4 | authors = ["Ferris Tseng "] 5 | edition = "2021" 6 | documentation = "https://docs.rs/ipfs-api" 7 | repository = "https://github.com/ferristseng/rust-ipfs-api" 8 | keywords = ["ipfs"] 9 | categories = ["filesystem", "web-programming"] 10 | version = "0.6.0" 11 | readme = "../README.md" 12 | license = "MIT OR Apache-2.0" 13 | 14 | [badges] 15 | github = { repository = "ferristseng/rust-ipfs-api", workflow = "Rust" } 16 | maintenance = { status = "passively-maintained" } 17 | 18 | [features] 19 | with-builder = ["typed-builder"] 20 | with-send-sync = [] 21 | 22 | [dependencies] 23 | async-trait = "0.1" 24 | bytes = "1" 25 | cfg-if = "1" 26 | common-multipart-rfc7578 = "0.6" 27 | dirs = "4" 28 | futures = "0.3" 29 | http = "0.2" 30 | multiaddr = "0.17" 31 | multibase = "0.9" 32 | serde = { version = "1", features = ["derive"] } 33 | serde_json = "1" 34 | serde_urlencoded = "0.7" 35 | thiserror = "1" 36 | tokio = "1" 37 | tokio-util = { version = "0.7", features = ["codec"] } 38 | tracing = "0.1" 39 | typed-builder = { version = "0.10", optional = true } 40 | walkdir = "2.3" 41 | 42 | [dev-dependencies] 43 | ipfs-api = { package = "ipfs-api-backend-hyper", path = "../ipfs-api-backend-hyper" } 44 | tokio = { version = "1", features = ["rt-multi-thread", "macros", "time"] } 45 | tokio-stream = { version = "0.1", features = ["time"] } 46 | tracing-subscriber = { version = "0.3", features = ["fmt"] } 47 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/error.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use std::{io, string::FromUtf8Error}; 10 | use thiserror::Error; 11 | 12 | #[derive(Debug, Error)] 13 | pub enum Error { 14 | #[error("io error `{0}`")] 15 | Io(#[from] io::Error), 16 | 17 | #[error("utf8 decoding error `{0}`")] 18 | ParseUtf8(#[from] FromUtf8Error), 19 | 20 | #[error("json decoding error `{0}`")] 21 | Parse(#[from] serde_json::Error), 22 | 23 | #[error("uri error `{0}`")] 24 | Url(#[from] http::uri::InvalidUri), 25 | 26 | #[error("url encoding error `{0}`")] 27 | EncodeUrl(#[from] serde_urlencoded::ser::Error), 28 | 29 | #[error("api returned an error while streaming `{0}`")] 30 | StreamError(String), 31 | 32 | #[error("api got unrecognized trailer header `{0}`")] 33 | UnrecognizedTrailerHeader(String), 34 | 35 | #[error("api returned an unknown error `{0}`")] 36 | UnrecognizedApiError(String), 37 | } 38 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/header.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | pub use http::header::TRAILER; 10 | 11 | pub const X_STREAM_ERROR: &str = "x-stream-error"; 12 | pub const X_STREAM_ERROR_KEY: &str = "X-Stream-Error"; 13 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | #[cfg(feature = "with-builder")] 10 | #[macro_use] 11 | extern crate typed_builder; 12 | 13 | extern crate serde; 14 | 15 | mod api; 16 | mod backend; 17 | mod error; 18 | mod from_uri; 19 | mod global_opts; 20 | mod header; 21 | mod read; 22 | pub mod request; 23 | pub mod response; 24 | 25 | pub use { 26 | api::IpfsApi, 27 | backend::{Backend, BoxStream}, 28 | error::Error, 29 | from_uri::TryFromUri, 30 | global_opts::{BackendWithGlobalOptions, GlobalOptions}, 31 | request::ApiRequest, 32 | response::ApiError, 33 | }; 34 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/add.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | use serde::Serialize; 11 | 12 | #[cfg_attr(feature = "with-builder", derive(TypedBuilder))] 13 | #[derive(Serialize, Default)] 14 | #[serde(rename_all = "kebab-case")] 15 | pub struct Add<'a> { 16 | /// Use trickle-dag format for dag generation. 17 | #[cfg_attr(feature = "with-builder", builder(default, setter(strip_option)))] 18 | pub trickle: Option, 19 | 20 | /// Only chunk and hash - do not write to disk. 21 | #[cfg_attr(feature = "with-builder", builder(default, setter(strip_option)))] 22 | pub only_hash: Option, 23 | 24 | /// Wrap files with a directory object. 25 | #[cfg_attr(feature = "with-builder", builder(default, setter(strip_option)))] 26 | pub wrap_with_directory: Option, 27 | 28 | /// Chunking algorithm, `size-[bytes]`, `rabin-[min]-[avg]-[max]` or `buzhash`. 29 | #[cfg_attr(feature = "with-builder", builder(default, setter(strip_option)))] 30 | pub chunker: Option<&'a str>, 31 | 32 | /// Pin this object when adding. Defaults to `true`. 33 | #[cfg_attr(feature = "with-builder", builder(default, setter(strip_option)))] 34 | pub pin: Option, 35 | 36 | /// Use raw blocks for leaf nodes. (experimental). 37 | #[cfg_attr(feature = "with-builder", builder(default, setter(strip_option)))] 38 | pub raw_leaves: Option, 39 | 40 | /// CID version. Defaults to 0 unless an option that depends on CIDv1 is passed. 41 | /// (experimental). 42 | #[cfg_attr(feature = "with-builder", builder(default, setter(strip_option)))] 43 | pub cid_version: Option, 44 | 45 | /// Hash function to use. Implies CIDv1 if not sha2-256. (experimental). Default: 46 | /// `sha2-256`. 47 | #[cfg_attr(feature = "with-builder", builder(default, setter(strip_option)))] 48 | pub hash: Option<&'a str>, 49 | 50 | /// Inline small blocks into CIDs. (experimental). 51 | #[cfg_attr(feature = "with-builder", builder(default, setter(strip_option)))] 52 | pub inline: Option, 53 | 54 | /// Maximum block size to inline. (experimental). Default: `32`. 55 | #[cfg_attr(feature = "with-builder", builder(default, setter(strip_option)))] 56 | pub inline_limit: Option, 57 | 58 | /// Add reference to Files API (MFS) at the provided path 59 | #[cfg_attr(feature = "with-builder", builder(default, setter(strip_option)))] 60 | pub to_files: Option<&'a str>, 61 | } 62 | 63 | impl<'a> ApiRequest for Add<'a> { 64 | const PATH: &'static str = "/add"; 65 | } 66 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/bitswap.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | use serde::Serialize; 11 | 12 | #[derive(Serialize)] 13 | pub struct BitswapLedger<'a> { 14 | #[serde(rename = "arg")] 15 | pub peer: &'a str, 16 | } 17 | 18 | impl<'a> ApiRequest for BitswapLedger<'a> { 19 | const PATH: &'static str = "/bitswap/ledger"; 20 | } 21 | 22 | pub struct BitswapReprovide; 23 | 24 | impl_skip_serialize!(BitswapReprovide); 25 | 26 | impl ApiRequest for BitswapReprovide { 27 | const PATH: &'static str = "/bitswap/reprovide"; 28 | } 29 | 30 | pub struct BitswapStat; 31 | 32 | impl_skip_serialize!(BitswapStat); 33 | 34 | impl ApiRequest for BitswapStat { 35 | const PATH: &'static str = "/bitswap/stat"; 36 | } 37 | 38 | #[derive(Serialize)] 39 | pub struct BitswapUnwant<'a> { 40 | #[serde(rename = "arg")] 41 | pub key: &'a str, 42 | } 43 | 44 | impl<'a> ApiRequest for BitswapUnwant<'a> { 45 | const PATH: &'static str = "/bitswap/stat"; 46 | } 47 | 48 | #[derive(Serialize)] 49 | pub struct BitswapWantlist<'a> { 50 | pub peer: Option<&'a str>, 51 | } 52 | 53 | impl<'a> ApiRequest for BitswapWantlist<'a> { 54 | const PATH: &'static str = "/bitswap/wantlist"; 55 | } 56 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/block.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | use serde::Serialize; 11 | 12 | #[derive(Serialize)] 13 | pub struct BlockGet<'a> { 14 | #[serde(rename = "arg")] 15 | pub hash: &'a str, 16 | } 17 | 18 | impl<'a> ApiRequest for BlockGet<'a> { 19 | const PATH: &'static str = "/block/get"; 20 | } 21 | 22 | #[cfg_attr(feature = "with-builder", derive(TypedBuilder))] 23 | #[derive(Serialize, Default)] 24 | #[serde(rename_all = "kebab-case")] 25 | pub struct BlockPut<'a> { 26 | #[cfg_attr(feature = "with-builder", builder(default, setter(strip_option)))] 27 | pub format: Option<&'a str>, 28 | #[cfg_attr(feature = "with-builder", builder(default, setter(strip_option)))] 29 | pub mhtype: Option<&'a str>, 30 | #[cfg_attr(feature = "with-builder", builder(default, setter(strip_option)))] 31 | pub mhlen: Option, 32 | #[cfg_attr(feature = "with-builder", builder(default, setter(strip_option)))] 33 | pub pin: Option, 34 | } 35 | 36 | impl<'a> ApiRequest for BlockPut<'a> { 37 | const PATH: &'static str = "/block/put"; 38 | } 39 | 40 | #[derive(Serialize)] 41 | pub struct BlockRm<'a> { 42 | #[serde(rename = "arg")] 43 | pub hash: &'a str, 44 | } 45 | 46 | impl<'a> ApiRequest for BlockRm<'a> { 47 | const PATH: &'static str = "/block/rm"; 48 | } 49 | 50 | #[derive(Serialize)] 51 | pub struct BlockStat<'a> { 52 | #[serde(rename = "arg")] 53 | pub hash: &'a str, 54 | } 55 | 56 | impl<'a> ApiRequest for BlockStat<'a> { 57 | const PATH: &'static str = "/block/stat"; 58 | } 59 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/bootstrap.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | 11 | pub struct BootstrapAddDefault; 12 | 13 | impl_skip_serialize!(BootstrapAddDefault); 14 | 15 | impl ApiRequest for BootstrapAddDefault { 16 | const PATH: &'static str = "/bootstrap/add/default"; 17 | } 18 | 19 | pub struct BootstrapList; 20 | 21 | impl_skip_serialize!(BootstrapList); 22 | 23 | impl ApiRequest for BootstrapList { 24 | const PATH: &'static str = "/bootstrap/list"; 25 | } 26 | 27 | pub struct BootstrapRmAll; 28 | 29 | impl_skip_serialize!(BootstrapRmAll); 30 | 31 | impl ApiRequest for BootstrapRmAll { 32 | const PATH: &'static str = "/bootstrap/rm/all"; 33 | } 34 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/cat.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | use serde::Serialize; 11 | 12 | #[derive(Serialize)] 13 | pub struct Cat<'a> { 14 | #[serde(rename = "arg")] 15 | pub path: &'a str, 16 | 17 | pub offset: Option, 18 | pub length: Option, 19 | } 20 | 21 | impl<'a> ApiRequest for Cat<'a> { 22 | const PATH: &'static str = "/cat"; 23 | } 24 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/commands.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | 11 | pub struct Commands; 12 | 13 | impl_skip_serialize!(Commands); 14 | 15 | impl ApiRequest for Commands { 16 | const PATH: &'static str = "/commands"; 17 | } 18 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/config.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | use serde::Serialize; 11 | 12 | #[derive(Serialize)] 13 | pub struct Config<'a> { 14 | #[serde(rename = "arg")] 15 | pub key: &'a str, 16 | 17 | #[serde(rename = "arg")] 18 | pub value: Option<&'a str>, 19 | 20 | #[serde(rename = "bool")] 21 | pub boolean: Option, 22 | 23 | #[serde(rename = "json")] 24 | pub stringified_json: Option, 25 | } 26 | 27 | impl<'a> ApiRequest for Config<'a> { 28 | const PATH: &'static str = "/config"; 29 | } 30 | 31 | pub struct ConfigEdit; 32 | 33 | impl_skip_serialize!(ConfigEdit); 34 | 35 | impl ApiRequest for ConfigEdit { 36 | const PATH: &'static str = "/config/edit"; 37 | } 38 | 39 | pub struct ConfigReplace; 40 | 41 | impl_skip_serialize!(ConfigReplace); 42 | 43 | impl ApiRequest for ConfigReplace { 44 | const PATH: &'static str = "/config/replace"; 45 | } 46 | 47 | pub struct ConfigShow; 48 | 49 | impl_skip_serialize!(ConfigShow); 50 | 51 | impl ApiRequest for ConfigShow { 52 | const PATH: &'static str = "/config/show"; 53 | } 54 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/dag.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | use serde::Serialize; 11 | 12 | #[derive(Debug, Serialize)] 13 | pub enum DagCodec { 14 | #[serde(rename = "dag-json")] 15 | Json, 16 | #[serde(rename = "dag-cbor")] 17 | Cbor, 18 | } 19 | 20 | #[cfg_attr(feature = "with-builder", derive(TypedBuilder))] 21 | #[derive(Serialize, Default)] 22 | pub struct DagGet<'a> { 23 | #[serde(rename = "arg")] 24 | pub path: &'a str, 25 | 26 | /// Format that the object will be encoded as. Default: dag-json. Required: no. 27 | #[serde(rename = "output-codec")] 28 | #[cfg_attr(feature = "with-builder", builder(default, setter(strip_option)))] 29 | pub codec: Option, 30 | } 31 | 32 | impl<'a> ApiRequest for DagGet<'a> { 33 | const PATH: &'static str = "/dag/get"; 34 | } 35 | 36 | #[cfg_attr(feature = "with-builder", derive(TypedBuilder))] 37 | #[derive(Serialize, Default)] 38 | #[serde(rename_all = "kebab-case")] 39 | pub struct DagPut<'a> { 40 | /// Codec that the stored object will be encoded with. Default: dag-cbor. Required: no. 41 | #[cfg_attr(feature = "with-builder", builder(default, setter(strip_option)))] 42 | pub store_codec: Option, 43 | /// Codec that the input object is encoded in. Default: dag-json. Required: no. 44 | #[cfg_attr(feature = "with-builder", builder(default, setter(strip_option)))] 45 | pub input_codec: Option, 46 | /// Pin this object when adding. Required: no. 47 | #[cfg_attr(feature = "with-builder", builder(default, setter(strip_option)))] 48 | pub pin: Option, 49 | /// Hash function to use. Default: sha2-256. Required: no. 50 | #[cfg_attr(feature = "with-builder", builder(default, setter(strip_option)))] 51 | pub hash: Option<&'a str>, 52 | } 53 | 54 | impl ApiRequest for DagPut<'_> { 55 | const PATH: &'static str = "/dag/put"; 56 | } 57 | 58 | #[cfg(test)] 59 | mod tests { 60 | use super::*; 61 | 62 | serialize_url_test!( 63 | test_serializes_dag_get, 64 | DagGet { 65 | path: "bafkreiglbo2l5lp25vteuexq3svg5hoad76mehz4tlrbwheslvluxcd63a", 66 | ..Default::default() 67 | }, 68 | "arg=bafkreiglbo2l5lp25vteuexq3svg5hoad76mehz4tlrbwheslvluxcd63a" 69 | ); 70 | 71 | serialize_url_test!( 72 | test_serializes_dag_get_with_options, 73 | DagGet { 74 | path: "bafkreiglbo2l5lp25vteuexq3svg5hoad76mehz4tlrbwheslvluxcd63a", 75 | codec: Some(DagCodec::Cbor), 76 | }, 77 | "arg=bafkreiglbo2l5lp25vteuexq3svg5hoad76mehz4tlrbwheslvluxcd63a&output-codec=dag-cbor" 78 | ); 79 | 80 | serialize_url_test!( 81 | test_serializes_dag_put, 82 | DagPut { 83 | ..Default::default() 84 | }, 85 | "" 86 | ); 87 | 88 | serialize_url_test!( 89 | test_serializes_dag_put_with_options, 90 | DagPut { 91 | store_codec: Some(DagCodec::Json), 92 | input_codec: Some(DagCodec::Cbor), 93 | pin: Some(false), 94 | hash: Some("sha3_384"), 95 | }, 96 | "store-codec=dag-json&input-codec=dag-cbor&pin=false&hash=sha3_384" 97 | ); 98 | } 99 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/dht.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | use serde::Serialize; 11 | 12 | #[derive(Serialize)] 13 | pub struct DhtFindPeer<'a> { 14 | #[serde(rename = "arg")] 15 | pub peer: &'a str, 16 | } 17 | 18 | impl<'a> ApiRequest for DhtFindPeer<'a> { 19 | const PATH: &'static str = "/dht/findpeer"; 20 | } 21 | 22 | #[derive(Serialize)] 23 | pub struct DhtFindProvs<'a> { 24 | #[serde(rename = "arg")] 25 | pub key: &'a str, 26 | } 27 | 28 | impl<'a> ApiRequest for DhtFindProvs<'a> { 29 | const PATH: &'static str = "/dht/findprovs"; 30 | } 31 | 32 | #[derive(Serialize)] 33 | pub struct DhtGet<'a> { 34 | #[serde(rename = "arg")] 35 | pub key: &'a str, 36 | } 37 | 38 | impl<'a> ApiRequest for DhtGet<'a> { 39 | const PATH: &'static str = "/dht/get"; 40 | } 41 | 42 | #[derive(Serialize)] 43 | pub struct DhtProvide<'a> { 44 | #[serde(rename = "arg")] 45 | pub key: &'a str, 46 | } 47 | 48 | impl<'a> ApiRequest for DhtProvide<'a> { 49 | const PATH: &'static str = "/dht/provide"; 50 | } 51 | 52 | #[derive(Serialize)] 53 | pub struct DhtPut<'a> { 54 | #[serde(rename = "arg")] 55 | pub key: &'a str, 56 | 57 | #[serde(rename = "arg")] 58 | pub value: &'a str, 59 | } 60 | 61 | impl<'a> ApiRequest for DhtPut<'a> { 62 | const PATH: &'static str = "/dht/put"; 63 | } 64 | 65 | #[derive(Serialize)] 66 | pub struct DhtQuery<'a> { 67 | #[serde(rename = "arg")] 68 | pub peer: &'a str, 69 | } 70 | 71 | impl<'a> ApiRequest for DhtQuery<'a> { 72 | const PATH: &'static str = "/dht/query"; 73 | } 74 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/diag.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | use serde::Serialize; 11 | 12 | pub struct DiagCmdsClear; 13 | 14 | impl_skip_serialize!(DiagCmdsClear); 15 | 16 | impl ApiRequest for DiagCmdsClear { 17 | const PATH: &'static str = "/diag/cmds/clear"; 18 | } 19 | 20 | #[derive(Serialize)] 21 | pub struct DiagCmdsSetTime<'a> { 22 | #[serde(rename = "arg")] 23 | pub time: &'a str, 24 | } 25 | 26 | impl<'a> ApiRequest for DiagCmdsSetTime<'a> { 27 | const PATH: &'static str = "/diag/cmds/set-time"; 28 | } 29 | 30 | pub struct DiagSys; 31 | 32 | impl_skip_serialize!(DiagSys); 33 | 34 | impl ApiRequest for DiagSys { 35 | const PATH: &'static str = "/diag/sys"; 36 | } 37 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/dns.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | use serde::Serialize; 11 | 12 | #[derive(Serialize)] 13 | pub struct Dns<'a> { 14 | #[serde(rename = "arg")] 15 | pub link: &'a str, 16 | 17 | pub recursive: bool, 18 | } 19 | 20 | impl<'a> ApiRequest for Dns<'a> { 21 | const PATH: &'static str = "/dns"; 22 | } 23 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/file.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | use serde::Serialize; 11 | 12 | #[derive(Serialize)] 13 | pub struct FileLs<'a> { 14 | #[serde(rename = "arg")] 15 | pub path: &'a str, 16 | } 17 | 18 | impl<'a> ApiRequest for FileLs<'a> { 19 | const PATH: &'static str = "/file/ls"; 20 | } 21 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/filestore.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | use serde::Serialize; 11 | 12 | pub struct FilestoreDups; 13 | 14 | impl_skip_serialize!(FilestoreDups); 15 | 16 | impl ApiRequest for FilestoreDups { 17 | const PATH: &'static str = "/filestore/dups"; 18 | } 19 | 20 | #[derive(Serialize)] 21 | pub struct FilestoreLs<'a> { 22 | #[serde(rename = "arg")] 23 | pub cid: Option<&'a str>, 24 | } 25 | 26 | impl<'a> ApiRequest for FilestoreLs<'a> { 27 | const PATH: &'static str = "/filestore/ls"; 28 | } 29 | 30 | #[derive(Serialize)] 31 | pub struct FilestoreVerify<'a> { 32 | #[serde(rename = "arg")] 33 | pub cid: Option<&'a str>, 34 | } 35 | 36 | impl<'a> ApiRequest for FilestoreVerify<'a> { 37 | const PATH: &'static str = "/filestore/verify"; 38 | } 39 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/get.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | use serde::Serialize; 11 | 12 | #[derive(Serialize)] 13 | pub struct Get<'a> { 14 | #[serde(rename = "arg")] 15 | pub path: &'a str, 16 | } 17 | 18 | impl<'a> ApiRequest for Get<'a> { 19 | const PATH: &'static str = "/get"; 20 | } 21 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/id.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | use serde::Serialize; 11 | 12 | #[derive(Serialize)] 13 | pub struct Id<'a> { 14 | #[serde(rename = "arg")] 15 | pub peer: Option<&'a str>, 16 | } 17 | 18 | impl<'a> ApiRequest for Id<'a> { 19 | const PATH: &'static str = "/id"; 20 | } 21 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/key.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | use serde::{Serialize, Serializer}; 11 | 12 | #[derive(Copy, Clone)] 13 | pub enum KeyType { 14 | Rsa, 15 | Ed25519, 16 | } 17 | 18 | impl Serialize for KeyType { 19 | fn serialize(&self, serializer: S) -> Result 20 | where 21 | S: Serializer, 22 | { 23 | let s = match self { 24 | KeyType::Rsa => "rsa", 25 | KeyType::Ed25519 => "ed25519", 26 | }; 27 | 28 | serializer.serialize_str(s) 29 | } 30 | } 31 | 32 | #[derive(Serialize)] 33 | pub struct KeyGen<'a> { 34 | #[serde(rename = "arg")] 35 | pub name: &'a str, 36 | 37 | #[serde(rename = "type")] 38 | pub kind: KeyType, 39 | 40 | pub size: i32, 41 | } 42 | 43 | impl<'a> ApiRequest for KeyGen<'a> { 44 | const PATH: &'static str = "/key/gen"; 45 | } 46 | 47 | pub struct KeyList; 48 | 49 | impl_skip_serialize!(KeyList); 50 | 51 | impl ApiRequest for KeyList { 52 | const PATH: &'static str = "/key/list"; 53 | } 54 | 55 | #[derive(Serialize)] 56 | pub struct KeyRename<'a, 'b> { 57 | #[serde(rename = "arg")] 58 | pub name: &'a str, 59 | 60 | #[serde(rename = "arg")] 61 | pub new: &'b str, 62 | 63 | pub force: bool, 64 | } 65 | 66 | impl<'a, 'b> ApiRequest for KeyRename<'a, 'b> { 67 | const PATH: &'static str = "/key/rename"; 68 | } 69 | 70 | #[derive(Serialize)] 71 | pub struct KeyRm<'a> { 72 | #[serde(rename = "arg")] 73 | pub name: &'a str, 74 | } 75 | 76 | impl<'a> ApiRequest for KeyRm<'a> { 77 | const PATH: &'static str = "/key/rm"; 78 | } 79 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/log.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | use serde::{Serialize, Serializer}; 11 | use std::borrow::Cow; 12 | 13 | #[derive(Copy, Clone)] 14 | pub enum LoggingLevel { 15 | Debug, 16 | Info, 17 | Warning, 18 | Error, 19 | Critical, 20 | } 21 | 22 | impl Serialize for LoggingLevel { 23 | fn serialize(&self, serializer: S) -> Result 24 | where 25 | S: Serializer, 26 | { 27 | let s = match self { 28 | LoggingLevel::Debug => "debug", 29 | LoggingLevel::Info => "info", 30 | LoggingLevel::Warning => "warning", 31 | LoggingLevel::Error => "error", 32 | LoggingLevel::Critical => "critical", 33 | }; 34 | 35 | serializer.serialize_str(s) 36 | } 37 | } 38 | 39 | pub enum Logger<'a> { 40 | All, 41 | Specific(Cow<'a, str>), 42 | } 43 | 44 | impl<'a> Serialize for Logger<'a> { 45 | fn serialize(&self, serializer: S) -> Result 46 | where 47 | S: Serializer, 48 | { 49 | let s = match self { 50 | Logger::All => "*", 51 | Logger::Specific(ref logger) => logger.as_ref(), 52 | }; 53 | 54 | serializer.serialize_str(s) 55 | } 56 | } 57 | 58 | #[derive(Serialize)] 59 | pub struct LogLevel<'a> { 60 | #[serde(rename = "arg")] 61 | pub logger: Logger<'a>, 62 | 63 | #[serde(rename = "arg")] 64 | pub level: LoggingLevel, 65 | } 66 | 67 | impl<'a> ApiRequest for LogLevel<'a> { 68 | const PATH: &'static str = "/log/level"; 69 | } 70 | 71 | pub struct LogLs; 72 | 73 | impl_skip_serialize!(LogLs); 74 | 75 | impl ApiRequest for LogLs { 76 | const PATH: &'static str = "/log/ls"; 77 | } 78 | 79 | pub struct LogTail; 80 | 81 | impl_skip_serialize!(LogTail); 82 | 83 | impl ApiRequest for LogTail { 84 | const PATH: &'static str = "/log/tail"; 85 | } 86 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/ls.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | use serde::Serialize; 11 | 12 | #[cfg_attr(feature = "with-builder", derive(TypedBuilder))] 13 | #[derive(Serialize, Default)] 14 | #[serde(rename_all = "kebab-case")] 15 | pub struct Ls<'a> { 16 | #[serde(rename = "arg")] 17 | pub path: &'a str, 18 | /// Resolve linked objects to find out their types. Default: `true` 19 | #[cfg_attr(feature = "with-builder", builder(default, setter(strip_option)))] 20 | pub resolve_type: Option, 21 | /// Resolve linked objects to find out their file size. Default: `true` 22 | #[cfg_attr(feature = "with-builder", builder(default, setter(strip_option)))] 23 | pub size: Option, 24 | /// Enable experimental streaming of directory entries as they are traversed. 25 | #[cfg_attr(feature = "with-builder", builder(default, setter(strip_option)))] 26 | pub stream: Option, 27 | } 28 | 29 | impl<'a> ApiRequest for Ls<'a> { 30 | const PATH: &'static str = "/ls"; 31 | } 32 | 33 | #[cfg(test)] 34 | mod tests { 35 | use super::Ls; 36 | 37 | serialize_url_test!( 38 | test_serializes_0, 39 | Ls { 40 | path: "test", 41 | ..Default::default() 42 | }, 43 | "arg=test" 44 | ); 45 | serialize_url_test!( 46 | test_serializes_1, 47 | Ls { 48 | path: "asdf", 49 | resolve_type: Some(true), 50 | size: Some(true), 51 | stream: Some(false) 52 | }, 53 | "arg=asdf&resolve-type=true&size=true&stream=false" 54 | ); 55 | } 56 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | pub use self::add::*; 10 | pub use self::bitswap::*; 11 | pub use self::block::*; 12 | pub use self::bootstrap::*; 13 | pub use self::cat::*; 14 | pub use self::commands::*; 15 | pub use self::config::*; 16 | pub use self::dag::*; 17 | pub use self::dht::*; 18 | pub use self::diag::*; 19 | pub use self::dns::*; 20 | pub use self::file::*; 21 | pub use self::files::*; 22 | pub use self::filestore::*; 23 | pub use self::get::*; 24 | pub use self::id::*; 25 | pub use self::key::*; 26 | pub use self::log::*; 27 | pub use self::ls::*; 28 | pub use self::name::*; 29 | pub use self::object::*; 30 | pub use self::pin::*; 31 | pub use self::ping::*; 32 | pub use self::pubsub::*; 33 | pub use self::refs::*; 34 | pub use self::shutdown::*; 35 | pub use self::stats::*; 36 | pub use self::swarm::*; 37 | pub use self::swarm_connect::*; 38 | pub use self::tar::*; 39 | pub use self::version::*; 40 | 41 | /// Create a test to verify that serializing a `ApiRequest` returns the expected 42 | /// url encoded string. 43 | /// 44 | #[cfg(test)] 45 | macro_rules! serialize_url_test { 46 | ($f: ident, $obj: expr, $exp: expr) => { 47 | #[test] 48 | fn $f() { 49 | assert_eq!(::serde_urlencoded::to_string($obj), Ok($exp.to_string())) 50 | } 51 | }; 52 | } 53 | 54 | /// Implements the `Serialize` trait for types that do not require 55 | /// serialization. This provides a workaround for a limitation in 56 | /// `serde_urlencoded`, that prevents unit structs from being serialized. 57 | /// 58 | macro_rules! impl_skip_serialize { 59 | ($ty: ty) => { 60 | impl ::serde::Serialize for $ty { 61 | fn serialize(&self, serializer: S) -> Result 62 | where 63 | S: ::serde::Serializer, 64 | { 65 | serializer.serialize_none() 66 | } 67 | } 68 | }; 69 | } 70 | 71 | mod add; 72 | mod bitswap; 73 | mod block; 74 | mod bootstrap; 75 | mod cat; 76 | mod commands; 77 | mod config; 78 | mod dag; 79 | mod dht; 80 | mod diag; 81 | mod dns; 82 | mod file; 83 | mod files; 84 | mod filestore; 85 | mod get; 86 | mod id; 87 | mod key; 88 | mod log; 89 | mod ls; 90 | mod name; 91 | mod object; 92 | mod pin; 93 | mod ping; 94 | mod pubsub; 95 | mod refs; 96 | mod shutdown; 97 | mod stats; 98 | mod swarm; 99 | mod swarm_connect; 100 | mod tar; 101 | mod version; 102 | 103 | use http::uri::Uri; 104 | use serde::Serialize; 105 | 106 | /// A request that can be made against the Ipfs API. 107 | /// 108 | pub trait ApiRequest: Serialize + Send { 109 | /// Returns the API path that this request can be called on. 110 | /// 111 | /// All paths should begin with '/'. 112 | /// 113 | const PATH: &'static str; 114 | 115 | /// Method used to make the request. 116 | /// 117 | const METHOD: http::Method = http::Method::POST; 118 | 119 | /// Creates the absolute URL for an API resource given the base path 120 | /// of the service. 121 | /// 122 | fn absolute_url(&self, base: &Uri) -> Result { 123 | format!( 124 | "{}{}?{}", 125 | base, 126 | Self::PATH, 127 | serde_urlencoded::to_string(self)? 128 | ) 129 | .parse() 130 | .map_err(crate::Error::from) 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/name.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | use serde::Serialize; 11 | 12 | #[derive(Serialize)] 13 | pub struct NamePublish<'a, 'b, 'c, 'd> { 14 | #[serde(rename = "arg")] 15 | pub path: &'a str, 16 | 17 | pub resolve: bool, 18 | 19 | pub lifetime: Option<&'b str>, 20 | 21 | pub ttl: Option<&'c str>, 22 | 23 | pub key: Option<&'d str>, 24 | } 25 | 26 | impl<'a, 'b, 'c, 'd> ApiRequest for NamePublish<'a, 'b, 'c, 'd> { 27 | const PATH: &'static str = "/name/publish"; 28 | } 29 | 30 | #[derive(Serialize)] 31 | pub struct NameResolve<'a> { 32 | #[serde(rename = "arg")] 33 | pub name: Option<&'a str>, 34 | 35 | pub recursive: bool, 36 | 37 | pub nocache: bool, 38 | } 39 | 40 | impl<'a> ApiRequest for NameResolve<'a> { 41 | const PATH: &'static str = "/name/resolve"; 42 | } 43 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/object.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | use serde::{Serialize, Serializer}; 11 | 12 | #[derive(Serialize)] 13 | pub struct ObjectData<'a> { 14 | #[serde(rename = "arg")] 15 | pub key: &'a str, 16 | } 17 | 18 | impl<'a> ApiRequest for ObjectData<'a> { 19 | const PATH: &'static str = "/object/data"; 20 | } 21 | 22 | #[derive(Serialize)] 23 | pub struct ObjectDiff<'a> { 24 | #[serde(rename = "arg")] 25 | pub key0: &'a str, 26 | 27 | #[serde(rename = "arg")] 28 | pub key1: &'a str, 29 | } 30 | 31 | impl<'a> ApiRequest for ObjectDiff<'a> { 32 | const PATH: &'static str = "/object/diff"; 33 | } 34 | 35 | #[derive(Serialize)] 36 | pub struct ObjectGet<'a> { 37 | #[serde(rename = "arg")] 38 | pub key: &'a str, 39 | } 40 | 41 | impl<'a> ApiRequest for ObjectGet<'a> { 42 | const PATH: &'static str = "/object/get"; 43 | } 44 | 45 | #[derive(Serialize)] 46 | pub struct ObjectLinks<'a> { 47 | #[serde(rename = "arg")] 48 | pub key: &'a str, 49 | } 50 | 51 | impl<'a> ApiRequest for ObjectLinks<'a> { 52 | const PATH: &'static str = "/object/links"; 53 | } 54 | 55 | #[derive(Copy, Clone)] 56 | pub enum ObjectTemplate { 57 | UnixFsDir, 58 | } 59 | 60 | impl Serialize for ObjectTemplate { 61 | fn serialize(&self, serializer: S) -> Result 62 | where 63 | S: Serializer, 64 | { 65 | let s = match self { 66 | ObjectTemplate::UnixFsDir => "unixfs-dir", 67 | }; 68 | 69 | serializer.serialize_str(s) 70 | } 71 | } 72 | 73 | #[derive(Serialize)] 74 | pub struct ObjectNew { 75 | #[serde(rename = "arg")] 76 | pub template: Option, 77 | } 78 | 79 | impl ApiRequest for ObjectNew { 80 | const PATH: &'static str = "/object/new"; 81 | } 82 | 83 | #[derive(Serialize)] 84 | pub struct ObjectPatchAddLink<'a> { 85 | #[serde(rename = "arg")] 86 | pub folder: &'a str, 87 | 88 | #[serde(rename = "arg")] 89 | pub name: &'a str, 90 | 91 | #[serde(rename = "arg")] 92 | pub key: &'a str, 93 | 94 | #[serde(rename = "create")] 95 | pub create: bool, 96 | } 97 | 98 | impl<'a> ApiRequest for ObjectPatchAddLink<'a> { 99 | const PATH: &'static str = "/object/patch/add-link"; 100 | } 101 | 102 | #[derive(Serialize)] 103 | pub struct ObjectStat<'a> { 104 | #[serde(rename = "arg")] 105 | pub key: &'a str, 106 | } 107 | 108 | impl<'a> ApiRequest for ObjectStat<'a> { 109 | const PATH: &'static str = "/object/stat"; 110 | } 111 | 112 | #[cfg(test)] 113 | mod tests { 114 | use super::ObjectDiff; 115 | 116 | serialize_url_test!( 117 | test_serializes_0, 118 | ObjectDiff { 119 | key0: "test", 120 | key1: "test2", 121 | }, 122 | "arg=test&arg=test2" 123 | ); 124 | } 125 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/pin.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | use serde::Serialize; 11 | 12 | #[derive(Serialize)] 13 | pub struct PinAdd<'a> { 14 | #[serde(rename = "arg")] 15 | pub key: &'a str, 16 | 17 | pub recursive: Option, 18 | pub progress: bool, 19 | } 20 | 21 | impl<'a> ApiRequest for PinAdd<'a> { 22 | const PATH: &'static str = "/pin/add"; 23 | } 24 | 25 | #[derive(Serialize)] 26 | pub struct PinLs<'a> { 27 | #[serde(rename = "arg")] 28 | pub key: Option<&'a str>, 29 | 30 | #[serde(rename = "type")] 31 | pub typ: Option<&'a str>, 32 | } 33 | 34 | impl<'a> ApiRequest for PinLs<'a> { 35 | const PATH: &'static str = "/pin/ls"; 36 | } 37 | 38 | #[derive(Serialize)] 39 | pub struct PinRm<'a> { 40 | #[serde(rename = "arg")] 41 | pub key: &'a str, 42 | 43 | pub recursive: bool, 44 | } 45 | 46 | impl<'a> ApiRequest for PinRm<'a> { 47 | const PATH: &'static str = "/pin/rm"; 48 | } 49 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/ping.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | use serde::Serialize; 11 | 12 | #[derive(Serialize)] 13 | pub struct Ping<'a> { 14 | #[serde(rename = "arg")] 15 | pub peer: &'a str, 16 | 17 | pub count: Option, 18 | } 19 | 20 | impl<'a> ApiRequest for Ping<'a> { 21 | const PATH: &'static str = "/ping"; 22 | } 23 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/pubsub.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | use crate::serde::ser::SerializeStruct; 11 | use multibase::{encode, Base}; 12 | use serde::{Serialize, Serializer}; 13 | 14 | pub struct PubsubLs; 15 | 16 | impl_skip_serialize!(PubsubLs); 17 | 18 | impl ApiRequest for PubsubLs { 19 | const PATH: &'static str = "/pubsub/ls"; 20 | } 21 | 22 | pub struct PubsubPeers<'a> { 23 | pub topic: Option<&'a [u8]>, 24 | } 25 | 26 | impl<'a> Serialize for PubsubPeers<'a> { 27 | fn serialize(&self, serializer: S) -> Result 28 | where 29 | S: Serializer, 30 | { 31 | let mut state = serializer.serialize_struct("PubsubPeers", 1)?; 32 | 33 | if let Some(topic) = self.topic { 34 | let topic = encode(Base::Base64Url, topic); 35 | 36 | state.serialize_field("arg", &topic)?; 37 | } else { 38 | state.serialize_field("arg", &Option::::None)?; 39 | } 40 | 41 | state.end() 42 | } 43 | } 44 | 45 | impl<'a> ApiRequest for PubsubPeers<'a> { 46 | const PATH: &'static str = "/pubsub/peers"; 47 | } 48 | 49 | pub struct PubsubPub<'a> { 50 | pub topic: &'a [u8], 51 | } 52 | 53 | impl<'a> Serialize for PubsubPub<'a> { 54 | fn serialize(&self, serializer: S) -> Result 55 | where 56 | S: Serializer, 57 | { 58 | let mut state = serializer.serialize_struct("PubsubPub", 1)?; 59 | 60 | let topic = encode(Base::Base64Url, self.topic); 61 | 62 | state.serialize_field("arg", &topic)?; 63 | 64 | state.end() 65 | } 66 | } 67 | 68 | impl<'a> ApiRequest for PubsubPub<'a> { 69 | const PATH: &'static str = "/pubsub/pub"; 70 | } 71 | 72 | pub struct PubsubSub<'a> { 73 | pub topic: &'a [u8], 74 | } 75 | 76 | impl<'a> Serialize for PubsubSub<'a> { 77 | fn serialize(&self, serializer: S) -> Result 78 | where 79 | S: Serializer, 80 | { 81 | let mut state = serializer.serialize_struct("PubsubSub", 1)?; 82 | 83 | let topic = encode(Base::Base64Url, self.topic); 84 | 85 | state.serialize_field("arg", &topic)?; 86 | 87 | state.end() 88 | } 89 | } 90 | 91 | impl<'a> ApiRequest for PubsubSub<'a> { 92 | const PATH: &'static str = "/pubsub/sub"; 93 | } 94 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/refs.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | 11 | pub struct RefsLocal; 12 | 13 | impl_skip_serialize!(RefsLocal); 14 | 15 | impl ApiRequest for RefsLocal { 16 | const PATH: &'static str = "/refs/local"; 17 | } 18 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/shutdown.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | 11 | pub struct Shutdown; 12 | 13 | impl_skip_serialize!(Shutdown); 14 | 15 | impl ApiRequest for Shutdown { 16 | const PATH: &'static str = "/shutdown"; 17 | } 18 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/stats.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | 11 | pub struct StatsBitswap; 12 | 13 | impl_skip_serialize!(StatsBitswap); 14 | 15 | impl ApiRequest for StatsBitswap { 16 | const PATH: &'static str = "/stats/bitswap"; 17 | } 18 | 19 | pub struct StatsBw; 20 | 21 | impl_skip_serialize!(StatsBw); 22 | 23 | impl ApiRequest for StatsBw { 24 | const PATH: &'static str = "/stats/bw"; 25 | } 26 | 27 | pub struct StatsRepo; 28 | 29 | impl_skip_serialize!(StatsRepo); 30 | 31 | impl ApiRequest for StatsRepo { 32 | const PATH: &'static str = "/stats/repo"; 33 | } 34 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/swarm.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | 11 | pub struct SwarmAddrsLocal; 12 | 13 | impl_skip_serialize!(SwarmAddrsLocal); 14 | 15 | impl ApiRequest for SwarmAddrsLocal { 16 | const PATH: &'static str = "/swarm/addrs/local"; 17 | } 18 | 19 | pub struct SwarmPeers; 20 | 21 | impl_skip_serialize!(SwarmPeers); 22 | 23 | impl ApiRequest for SwarmPeers { 24 | const PATH: &'static str = "/swarm/peers"; 25 | } 26 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/swarm_connect.rs: -------------------------------------------------------------------------------- 1 | use crate::request::ApiRequest; 2 | use serde::Serialize; 3 | 4 | #[derive(Serialize)] 5 | pub struct SwarmConnect<'a> { 6 | #[serde(rename = "arg")] 7 | pub peer: &'a str, 8 | } 9 | impl<'a> ApiRequest for SwarmConnect<'a> { 10 | const PATH: &'static str = "/swarm/connect"; 11 | } 12 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/tar.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | use serde::Serialize; 11 | 12 | pub struct TarAdd; 13 | 14 | impl_skip_serialize!(TarAdd); 15 | 16 | impl ApiRequest for TarAdd { 17 | const PATH: &'static str = "/tar/add"; 18 | } 19 | 20 | #[derive(Serialize)] 21 | pub struct TarCat<'a> { 22 | #[serde(rename = "arg")] 23 | pub path: &'a str, 24 | } 25 | 26 | impl<'a> ApiRequest for TarCat<'a> { 27 | const PATH: &'static str = "/tar/cat"; 28 | } 29 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/request/version.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::request::ApiRequest; 10 | 11 | pub struct Version; 12 | 13 | impl_skip_serialize!(Version); 14 | 15 | impl ApiRequest for Version { 16 | const PATH: &'static str = "/version"; 17 | } 18 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/add.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::serde::Deserialize; 10 | 11 | #[derive(Debug, Deserialize)] 12 | #[serde(rename_all = "PascalCase")] 13 | pub struct AddResponse { 14 | pub name: String, 15 | pub hash: String, 16 | pub size: String, 17 | } 18 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/bitswap.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::response::serde; 10 | use crate::serde::Deserialize; 11 | 12 | #[derive(Debug, Deserialize)] 13 | #[serde(rename_all = "PascalCase")] 14 | pub struct BitswapLedgerResponse { 15 | pub peer: String, 16 | pub value: f64, 17 | pub sent: u64, 18 | pub recv: u64, 19 | pub exchanged: u64, 20 | } 21 | 22 | pub type BitswapReprovideResponse = (); 23 | 24 | #[derive(Debug, Deserialize)] 25 | #[serde(rename_all = "PascalCase")] 26 | pub struct BitswapStatResponse { 27 | pub provide_buf_len: i32, 28 | 29 | #[serde(deserialize_with = "serde::deserialize_vec")] 30 | pub wantlist: Vec, 31 | 32 | #[serde(deserialize_with = "serde::deserialize_vec")] 33 | pub peers: Vec, 34 | 35 | pub blocks_received: u64, 36 | pub data_received: u64, 37 | pub blocks_sent: u64, 38 | pub data_sent: u64, 39 | pub dup_blks_received: u64, 40 | pub dup_data_received: u64, 41 | } 42 | 43 | pub type BitswapUnwantResponse = (); 44 | 45 | #[derive(Debug, Deserialize)] 46 | #[serde(rename_all = "PascalCase")] 47 | pub struct BitswapWantlistResponse { 48 | #[serde(deserialize_with = "serde::deserialize_vec")] 49 | pub keys: Vec, 50 | } 51 | 52 | #[cfg(test)] 53 | mod tests { 54 | deserialize_test!(v0_bitswap_stat_0, BitswapStatResponse); 55 | } 56 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/block.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::serde::Deserialize; 10 | 11 | #[derive(Debug, Deserialize)] 12 | #[serde(rename_all = "PascalCase")] 13 | pub struct BlockPutResponse { 14 | pub key: String, 15 | pub size: u64, 16 | } 17 | 18 | #[derive(Debug, Deserialize)] 19 | #[serde(rename_all = "PascalCase")] 20 | pub struct BlockRmResponse { 21 | pub hash: String, 22 | pub error: Option, 23 | } 24 | 25 | #[derive(Debug, Deserialize)] 26 | #[serde(rename_all = "PascalCase")] 27 | pub struct BlockStatResponse { 28 | pub key: String, 29 | pub size: u64, 30 | } 31 | 32 | #[cfg(test)] 33 | mod tests { 34 | deserialize_test!(v0_block_stat_0, BlockStatResponse); 35 | } 36 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/bootstrap.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::response::serde; 10 | use crate::serde::Deserialize; 11 | 12 | #[derive(Debug, Deserialize)] 13 | #[serde(rename_all = "PascalCase")] 14 | pub struct BootstrapAddDefaultResponse { 15 | #[serde(deserialize_with = "serde::deserialize_vec")] 16 | pub peers: Vec, 17 | } 18 | 19 | #[derive(Debug, Deserialize)] 20 | #[serde(rename_all = "PascalCase")] 21 | pub struct BootstrapListResponse { 22 | #[serde(deserialize_with = "serde::deserialize_vec")] 23 | pub peers: Vec, 24 | } 25 | 26 | #[derive(Debug, Deserialize)] 27 | #[serde(rename_all = "PascalCase")] 28 | pub struct BootstrapRmAllResponse { 29 | #[serde(deserialize_with = "serde::deserialize_vec")] 30 | pub peers: Vec, 31 | } 32 | 33 | #[cfg(test)] 34 | mod tests { 35 | deserialize_test!(v0_bootstrap_list_0, BootstrapListResponse); 36 | } 37 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/commands.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::response::serde; 10 | use crate::serde::Deserialize; 11 | 12 | #[derive(Debug, Deserialize)] 13 | #[serde(rename_all = "PascalCase")] 14 | pub struct CommandsResponseOptions { 15 | #[serde(deserialize_with = "serde::deserialize_vec")] 16 | pub names: Vec, 17 | } 18 | 19 | #[derive(Debug, Deserialize)] 20 | #[serde(rename_all = "PascalCase")] 21 | pub struct CommandsResponse { 22 | pub name: String, 23 | 24 | #[serde(deserialize_with = "serde::deserialize_vec")] 25 | pub subcommands: Vec, 26 | 27 | #[serde(deserialize_with = "serde::deserialize_vec")] 28 | pub options: Vec, 29 | } 30 | 31 | #[cfg(test)] 32 | mod tests { 33 | deserialize_test!(v0_commands_0, CommandsResponse); 34 | } 35 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/config.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::serde::Deserialize; 10 | 11 | #[derive(Debug, Deserialize)] 12 | #[serde(rename_all = "PascalCase")] 13 | pub struct ConfigResponse { 14 | pub key: String, 15 | 16 | pub value: serde_json::value::Value, 17 | } 18 | 19 | pub type ConfigEditResponse = (); 20 | 21 | pub type ConfigReplaceResponse = (); 22 | 23 | pub type ConfigShowResponse = String; 24 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/dag.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::response::serde; 10 | use crate::serde::Deserialize; 11 | use std::collections::HashMap; 12 | 13 | #[derive(Debug, Deserialize)] 14 | #[serde(rename_all = "PascalCase")] 15 | pub struct DagIpfsHeader { 16 | pub name: String, 17 | pub size: u64, 18 | 19 | #[serde(deserialize_with = "serde::deserialize_hashmap")] 20 | pub cid: HashMap, 21 | } 22 | 23 | #[derive(Debug, Deserialize)] 24 | pub struct DagGetResponse { 25 | pub data: Option, 26 | 27 | #[serde(deserialize_with = "serde::deserialize_vec")] 28 | pub links: Vec, 29 | } 30 | 31 | #[derive(Debug, Deserialize)] 32 | pub struct DagPutResponse { 33 | #[serde(rename = "Cid")] 34 | pub cid: Cid, 35 | } 36 | 37 | #[derive(Debug, Deserialize)] 38 | pub struct Cid { 39 | #[serde(rename = "/")] 40 | pub cid_string: String, 41 | } 42 | 43 | #[cfg(test)] 44 | mod tests { 45 | deserialize_test!(v0_dag_get_0, DagGetResponse); 46 | } 47 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/dht.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::response::serde; 10 | use crate::serde::{ 11 | de::{Deserializer, Error}, 12 | Deserialize, 13 | }; 14 | 15 | /// See 16 | /// [libp2p](https://github.com/libp2p/go-libp2p-routing/blob/master/notifications/query.go#L16). 17 | /// 18 | #[derive(Debug)] 19 | pub enum DhtType { 20 | SendingQuery, 21 | PeerResponse, 22 | FinalPeer, 23 | QueryError, 24 | Provider, 25 | Value, 26 | AddingPeer, 27 | DialingPeer, 28 | } 29 | 30 | impl<'de> Deserialize<'de> for DhtType { 31 | #[inline] 32 | fn deserialize(deserializer: D) -> Result 33 | where 34 | D: Deserializer<'de>, 35 | { 36 | match deserializer.deserialize_i64(serde::IntegerVisitor)? { 37 | 0 => Ok(DhtType::SendingQuery), 38 | 1 => Ok(DhtType::PeerResponse), 39 | 2 => Ok(DhtType::FinalPeer), 40 | 3 => Ok(DhtType::QueryError), 41 | 4 => Ok(DhtType::Provider), 42 | 5 => Ok(DhtType::Value), 43 | 6 => Ok(DhtType::AddingPeer), 44 | 7 => Ok(DhtType::DialingPeer), 45 | i => Err(D::Error::custom(format!("unknown dht type '{}'", i))), 46 | } 47 | } 48 | } 49 | 50 | #[derive(Debug, Deserialize)] 51 | #[serde(rename_all = "PascalCase")] 52 | pub struct DhtPeerResponse { 53 | #[serde(rename = "ID")] 54 | pub id: String, 55 | 56 | #[serde(deserialize_with = "serde::deserialize_vec")] 57 | pub addrs: Vec, 58 | } 59 | 60 | #[derive(Debug, Deserialize)] 61 | #[serde(rename_all = "PascalCase")] 62 | pub struct DhtMessage { 63 | #[serde(rename = "ID")] 64 | pub id: String, 65 | 66 | #[serde(rename = "Type")] 67 | pub typ: DhtType, 68 | 69 | #[serde(deserialize_with = "serde::deserialize_vec")] 70 | pub responses: Vec, 71 | 72 | pub extra: String, 73 | } 74 | 75 | pub type DhtFindPeerResponse = DhtMessage; 76 | 77 | pub type DhtFindProvsResponse = DhtMessage; 78 | 79 | pub type DhtGetResponse = DhtMessage; 80 | 81 | pub type DhtProvideResponse = DhtMessage; 82 | 83 | pub type DhtPutResponse = DhtMessage; 84 | 85 | pub type DhtQueryResponse = DhtMessage; 86 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/diag.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | pub type DiagCmdsClearResponse = (); 10 | 11 | pub type DiagCmdsSetTimeResponse = (); 12 | 13 | pub type DiagSysResponse = String; 14 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/dns.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::serde::Deserialize; 10 | 11 | #[derive(Debug, Deserialize)] 12 | #[serde(rename_all = "PascalCase")] 13 | pub struct DnsResponse { 14 | pub path: String, 15 | } 16 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/error.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::serde::Deserialize; 10 | use std::fmt::{self, Display, Formatter}; 11 | 12 | #[derive(Debug, Deserialize)] 13 | #[serde(rename_all = "PascalCase")] 14 | pub struct ApiError { 15 | pub message: String, 16 | pub code: u8, 17 | } 18 | 19 | impl Display for ApiError { 20 | fn fmt(&self, formatter: &mut Formatter<'_>) -> Result<(), fmt::Error> { 21 | write!(formatter, "[{}] {}", self.code, self.message) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/file.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::response::{serde, IpfsHeader}; 10 | use crate::serde::Deserialize; 11 | use std::collections::HashMap; 12 | 13 | #[derive(Debug, Deserialize)] 14 | #[serde(rename_all = "PascalCase")] 15 | pub struct IpfsDetailedFile { 16 | pub hash: String, 17 | pub size: u64, 18 | 19 | #[serde(rename = "Type")] 20 | pub typ: String, 21 | 22 | #[serde(default)] 23 | pub links: Vec, 24 | } 25 | 26 | #[derive(Debug, Deserialize)] 27 | #[serde(rename_all = "PascalCase")] 28 | pub struct FileLsResponse { 29 | #[serde(deserialize_with = "serde::deserialize_hashmap")] 30 | pub arguments: HashMap, 31 | 32 | #[serde(deserialize_with = "serde::deserialize_hashmap")] 33 | pub objects: HashMap, 34 | } 35 | 36 | #[cfg(test)] 37 | mod tests { 38 | deserialize_test!(v0_file_ls_0, FileLsResponse); 39 | deserialize_test!(v0_file_ls_1, FileLsResponse); 40 | } 41 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/files.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::response::serde; 10 | use crate::serde::Deserialize; 11 | 12 | pub type FilesCpResponse = (); 13 | 14 | pub type FilesFlushResponse = (); 15 | 16 | #[derive(Debug, Deserialize)] 17 | #[serde(rename_all = "PascalCase")] 18 | pub struct FilesEntry { 19 | pub name: String, 20 | 21 | // This is a protocol buffer enum type defined in 22 | // https://github.com/ipfs/go-ipfs/blob/master/unixfs/pb/unixfs.proto ... 23 | // So it might be some other type than u64, but certainly shouldn't be *bigger* than u64. 24 | #[serde(rename = "Type")] 25 | pub typ: u64, 26 | pub size: u64, 27 | pub hash: String, 28 | } 29 | 30 | #[derive(Debug, Deserialize)] 31 | #[serde(rename_all = "PascalCase")] 32 | pub struct FilesLsResponse { 33 | #[serde(deserialize_with = "serde::deserialize_vec")] 34 | pub entries: Vec, 35 | } 36 | 37 | pub type FilesMkdirResponse = (); 38 | 39 | pub type FilesMvResponse = (); 40 | 41 | pub type FilesRmResponse = (); 42 | 43 | #[derive(Debug, Deserialize)] 44 | #[serde(rename_all = "PascalCase")] 45 | pub struct FilesStatResponse { 46 | pub hash: String, 47 | pub size: u64, 48 | pub cumulative_size: u64, 49 | pub blocks: u64, 50 | 51 | #[serde(rename = "Type")] 52 | pub typ: String, 53 | 54 | #[serde(default)] 55 | pub size_local: Option, 56 | #[serde(default)] 57 | pub local: Option, 58 | } 59 | 60 | pub type FilesWriteResponse = (); 61 | 62 | pub type FilesChcidResponse = (); 63 | 64 | #[cfg(test)] 65 | mod tests { 66 | deserialize_test!(v0_files_ls_0, FilesLsResponse); 67 | deserialize_test!(v0_files_stat_0, FilesStatResponse); 68 | } 69 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/filestore.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::serde::Deserialize; 10 | 11 | #[derive(Debug, Deserialize)] 12 | #[serde(rename_all = "PascalCase")] 13 | pub struct FilestoreDupsResponse { 14 | #[serde(rename = "Ref")] 15 | pub reference: String, 16 | 17 | pub err: String, 18 | } 19 | 20 | #[derive(Debug, Deserialize)] 21 | #[serde(rename_all = "PascalCase")] 22 | pub struct FilestoreObject { 23 | pub status: i32, 24 | pub error_msg: String, 25 | pub key: String, 26 | pub file_path: String, 27 | pub offset: u64, 28 | pub size: u64, 29 | } 30 | 31 | pub type FilestoreLsResponse = FilestoreObject; 32 | 33 | pub type FilestoreVerifyResponse = FilestoreObject; 34 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/id.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::response::serde; 10 | use crate::serde::Deserialize; 11 | 12 | #[derive(Debug, Deserialize)] 13 | #[serde(rename_all = "PascalCase")] 14 | pub struct IdResponse { 15 | #[serde(rename = "ID")] 16 | pub id: String, 17 | 18 | pub public_key: String, 19 | 20 | #[serde(deserialize_with = "serde::deserialize_vec")] 21 | pub addresses: Vec, 22 | #[serde(deserialize_with = "serde::deserialize_vec")] 23 | pub protocols: Vec, 24 | 25 | pub agent_version: String, 26 | } 27 | 28 | #[cfg(test)] 29 | mod tests { 30 | deserialize_test!(v0_id_0, IdResponse); 31 | } 32 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/key.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::response::serde; 10 | use crate::serde::Deserialize; 11 | 12 | #[derive(Debug, Deserialize)] 13 | #[serde(rename_all = "PascalCase")] 14 | pub struct KeyPair { 15 | pub name: String, 16 | pub id: String, 17 | } 18 | 19 | #[derive(Debug, Deserialize)] 20 | #[serde(rename_all = "PascalCase")] 21 | pub struct KeyPairList { 22 | #[serde(deserialize_with = "serde::deserialize_vec")] 23 | pub keys: Vec, 24 | } 25 | 26 | pub type KeyGenResponse = KeyPair; 27 | 28 | pub type KeyListResponse = KeyPairList; 29 | 30 | #[derive(Debug, Deserialize)] 31 | #[serde(rename_all = "PascalCase")] 32 | pub struct KeyRenameResponse { 33 | pub was: String, 34 | pub now: String, 35 | pub id: String, 36 | pub overwrite: bool, 37 | } 38 | 39 | pub type KeyRmResponse = KeyPairList; 40 | 41 | #[cfg(test)] 42 | mod tests { 43 | deserialize_test!(v0_key_gen_0, KeyGenResponse); 44 | deserialize_test!(v0_key_list_0, KeyListResponse); 45 | deserialize_test!(v0_key_rename_0, KeyRenameResponse); 46 | } 47 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/log.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::response::serde; 10 | use crate::serde::Deserialize; 11 | 12 | #[derive(Debug, Deserialize)] 13 | #[serde(rename_all = "PascalCase")] 14 | pub struct LogLevelResponse { 15 | pub message: String, 16 | } 17 | 18 | #[derive(Debug, Deserialize)] 19 | #[serde(rename_all = "PascalCase")] 20 | pub struct LogLsResponse { 21 | #[serde(deserialize_with = "serde::deserialize_vec")] 22 | pub strings: Vec, 23 | } 24 | 25 | #[cfg(test)] 26 | mod tests { 27 | deserialize_test!(v0_log_ls_0, LogLsResponse); 28 | } 29 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/ls.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::response::serde; 10 | use crate::serde::Deserialize; 11 | 12 | #[derive(Deserialize)] 13 | #[serde(rename_all = "PascalCase")] 14 | pub struct IpfsFile { 15 | pub hash: String, 16 | 17 | #[serde(deserialize_with = "serde::deserialize_vec")] 18 | pub links: Vec, 19 | } 20 | 21 | #[derive(Deserialize)] 22 | #[serde(rename_all = "PascalCase")] 23 | pub struct IpfsFileHeader { 24 | pub name: String, 25 | pub hash: String, 26 | pub size: u64, 27 | 28 | #[serde(rename = "Type")] 29 | pub typ: u32, 30 | } 31 | 32 | #[derive(Deserialize)] 33 | #[serde(rename_all = "PascalCase")] 34 | pub struct LsResponse { 35 | #[serde(deserialize_with = "serde::deserialize_vec")] 36 | pub objects: Vec, 37 | } 38 | 39 | #[cfg(test)] 40 | mod tests { 41 | deserialize_test!(v0_ls_0, LsResponse); 42 | deserialize_test!(v0_ls_1, LsResponse); 43 | } 44 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | //! This module contains structures returned by the IPFS API. 10 | 11 | use crate::serde::Deserialize; 12 | 13 | pub use self::add::*; 14 | pub use self::bitswap::*; 15 | pub use self::block::*; 16 | pub use self::bootstrap::*; 17 | pub use self::commands::*; 18 | pub use self::config::*; 19 | pub use self::dag::*; 20 | pub use self::dht::*; 21 | pub use self::diag::*; 22 | pub use self::dns::*; 23 | pub use self::error::*; 24 | pub use self::file::*; 25 | pub use self::files::*; 26 | pub use self::filestore::*; 27 | pub use self::id::*; 28 | pub use self::key::*; 29 | pub use self::log::*; 30 | pub use self::ls::*; 31 | pub use self::mount::*; 32 | pub use self::name::*; 33 | pub use self::object::*; 34 | pub use self::pin::*; 35 | pub use self::ping::*; 36 | pub use self::pubsub::*; 37 | pub use self::refs::*; 38 | pub use self::repo::*; 39 | pub use self::resolve::*; 40 | pub use self::shutdown::*; 41 | pub use self::stats::*; 42 | pub use self::swarm::*; 43 | pub use self::swarm_connect::*; 44 | pub use self::tar::*; 45 | pub use self::version::*; 46 | 47 | /// Create a test to deserialize a file to the given instance. 48 | /// 49 | #[cfg(test)] 50 | macro_rules! deserialize_test { 51 | ($f: ident, $ty: ident) => { 52 | #[test] 53 | fn $f() { 54 | let raw = include_str!(concat!("tests/", stringify!($f), ".json")); 55 | 56 | match ::serde_json::from_str::(raw) { 57 | Ok(_) => assert!(true), 58 | Err(e) => assert!(false, "failed with error: {}", e), 59 | }; 60 | } 61 | }; 62 | } 63 | 64 | mod add; 65 | mod bitswap; 66 | mod block; 67 | mod bootstrap; 68 | mod commands; 69 | mod config; 70 | mod dag; 71 | mod dht; 72 | mod diag; 73 | mod dns; 74 | mod error; 75 | mod file; 76 | mod files; 77 | mod filestore; 78 | mod id; 79 | mod key; 80 | mod log; 81 | mod ls; 82 | mod mount; 83 | mod name; 84 | mod object; 85 | mod pin; 86 | mod ping; 87 | mod pubsub; 88 | mod refs; 89 | mod repo; 90 | mod resolve; 91 | mod serde; 92 | mod shutdown; 93 | mod stats; 94 | mod swarm; 95 | mod swarm_connect; 96 | mod tar; 97 | mod version; 98 | 99 | #[derive(Debug, Deserialize)] 100 | #[serde(rename_all = "PascalCase")] 101 | pub struct IpfsHeader { 102 | pub name: String, 103 | pub hash: String, 104 | pub size: u64, 105 | 106 | #[serde(rename = "Type")] 107 | pub typ: Option, 108 | } 109 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/mount.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::serde::Deserialize; 10 | 11 | #[derive(Deserialize)] 12 | #[serde(rename_all = "PascalCase")] 13 | pub struct MountResponse { 14 | #[serde(rename = "IPFS")] 15 | pub ipfs: String, 16 | 17 | #[serde(rename = "IPNS")] 18 | pub ipns: String, 19 | 20 | pub fuse_allow_other: bool, 21 | } 22 | 23 | #[cfg(test)] 24 | mod tests { 25 | deserialize_test!(v0_mount_0, MountResponse); 26 | } 27 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/name.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::serde::Deserialize; 10 | 11 | #[derive(Deserialize)] 12 | #[serde(rename_all = "PascalCase")] 13 | pub struct NamePublishResponse { 14 | pub name: String, 15 | pub value: String, 16 | } 17 | 18 | #[derive(Deserialize)] 19 | #[serde(rename_all = "PascalCase")] 20 | pub struct NameResolveResponse { 21 | pub path: String, 22 | } 23 | 24 | #[cfg(test)] 25 | mod tests { 26 | deserialize_test!(v0_name_resolve_0, NameResolveResponse); 27 | } 28 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/object.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::response::{serde, IpfsHeader}; 10 | use crate::serde::Deserialize; 11 | use std::collections::HashMap; 12 | 13 | #[derive(Debug, Deserialize)] 14 | #[serde(rename_all = "PascalCase")] 15 | pub struct ObjectDiff { 16 | #[serde(rename = "Type")] 17 | pub typ: u64, 18 | 19 | pub path: String, 20 | 21 | #[serde(deserialize_with = "serde::deserialize_hashmap")] 22 | pub before: HashMap, 23 | 24 | #[serde(deserialize_with = "serde::deserialize_hashmap")] 25 | pub after: HashMap, 26 | } 27 | 28 | #[derive(Debug, Deserialize)] 29 | #[serde(rename_all = "PascalCase")] 30 | pub struct ObjectDiffResponse { 31 | #[serde(deserialize_with = "serde::deserialize_vec")] 32 | pub changes: Vec, 33 | } 34 | 35 | #[derive(Debug, Deserialize)] 36 | #[serde(rename_all = "PascalCase")] 37 | pub struct ObjectGetResponse { 38 | pub data: String, 39 | 40 | #[serde(deserialize_with = "serde::deserialize_vec")] 41 | pub links: Vec, 42 | } 43 | 44 | #[derive(Debug, Deserialize)] 45 | #[serde(rename_all = "PascalCase")] 46 | pub struct ObjectLinksResponse { 47 | pub hash: String, 48 | 49 | #[serde(deserialize_with = "serde::deserialize_vec")] 50 | pub links: Vec, 51 | } 52 | 53 | #[derive(Deserialize)] 54 | #[serde(rename_all = "PascalCase")] 55 | pub struct ObjectNewResponse { 56 | pub hash: String, 57 | 58 | #[serde(deserialize_with = "serde::deserialize_vec")] 59 | #[serde(default)] 60 | pub links: Vec, 61 | } 62 | 63 | #[derive(Deserialize)] 64 | #[serde(rename_all = "PascalCase")] 65 | pub struct ObjectPatchAddLinkResponse { 66 | pub hash: String, 67 | 68 | #[serde(deserialize_with = "serde::deserialize_vec")] 69 | #[serde(default)] 70 | pub links: Vec, 71 | } 72 | 73 | #[derive(Deserialize)] 74 | #[serde(rename_all = "PascalCase")] 75 | pub struct ObjectPatchAppendDataResponse { 76 | pub hash: String, 77 | 78 | #[serde(deserialize_with = "serde::deserialize_vec")] 79 | pub links: Vec, 80 | } 81 | 82 | #[derive(Deserialize)] 83 | #[serde(rename_all = "PascalCase")] 84 | pub struct ObjectPatchRmLinkResponse { 85 | pub hash: String, 86 | 87 | #[serde(deserialize_with = "serde::deserialize_vec")] 88 | pub links: Vec, 89 | } 90 | 91 | #[derive(Deserialize)] 92 | #[serde(rename_all = "PascalCase")] 93 | pub struct ObjectPatchSetDataResponse { 94 | pub hash: String, 95 | 96 | #[serde(deserialize_with = "serde::deserialize_vec")] 97 | pub links: Vec, 98 | } 99 | 100 | #[derive(Deserialize)] 101 | #[serde(rename_all = "PascalCase")] 102 | pub struct ObjectPutResponse { 103 | pub hash: String, 104 | 105 | #[serde(deserialize_with = "serde::deserialize_vec")] 106 | pub links: Vec, 107 | } 108 | 109 | #[derive(Debug, Deserialize)] 110 | #[serde(rename_all = "PascalCase")] 111 | pub struct ObjectStatResponse { 112 | pub hash: String, 113 | pub num_links: u64, 114 | pub block_size: u64, 115 | pub links_size: u64, 116 | pub data_size: u64, 117 | pub cumulative_size: u64, 118 | } 119 | 120 | #[cfg(test)] 121 | mod tests { 122 | deserialize_test!(v0_object_diff_0, ObjectDiffResponse); 123 | deserialize_test!(v0_object_links_0, ObjectLinksResponse); 124 | deserialize_test!(v0_object_stat_0, ObjectStatResponse); 125 | } 126 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/pin.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::response::serde; 10 | use crate::serde::Deserialize; 11 | use std::collections::HashMap; 12 | 13 | #[derive(Debug, Deserialize)] 14 | #[serde(rename_all = "PascalCase")] 15 | pub struct PinAddResponse { 16 | #[serde(deserialize_with = "serde::deserialize_vec")] 17 | pub pins: Vec, 18 | 19 | pub progress: Option, 20 | } 21 | 22 | #[derive(Debug, Deserialize)] 23 | #[serde(rename_all = "PascalCase")] 24 | pub struct PinType { 25 | #[serde(rename = "Type")] 26 | pub typ: String, 27 | } 28 | 29 | #[derive(Debug, Deserialize)] 30 | #[serde(rename_all = "PascalCase")] 31 | pub struct PinLsResponse { 32 | #[serde(deserialize_with = "serde::deserialize_hashmap")] 33 | pub keys: HashMap, 34 | } 35 | 36 | #[derive(Debug, Deserialize)] 37 | #[serde(rename_all = "PascalCase")] 38 | pub struct PinRmResponse { 39 | #[serde(deserialize_with = "serde::deserialize_vec")] 40 | pub pins: Vec, 41 | } 42 | 43 | #[cfg(test)] 44 | mod tests { 45 | deserialize_test!(v0_pin_ls_0, PinLsResponse); 46 | deserialize_test!(v0_pin_add_0, PinAddResponse); 47 | } 48 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/ping.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::serde::Deserialize; 10 | 11 | #[derive(Debug, Deserialize)] 12 | #[serde(rename_all = "PascalCase")] 13 | pub struct PingResponse { 14 | pub success: bool, 15 | pub time: i64, 16 | pub text: String, 17 | } 18 | 19 | #[cfg(test)] 20 | mod tests { 21 | deserialize_test!(v0_ping_0, PingResponse); 22 | deserialize_test!(v0_ping_1, PingResponse); 23 | deserialize_test!(v0_ping_2, PingResponse); 24 | } 25 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/pubsub.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::response::serde; 10 | use crate::serde::Deserialize; 11 | 12 | #[derive(Debug, Deserialize)] 13 | #[serde(rename_all = "PascalCase")] 14 | pub struct PubsubLsResponse { 15 | #[serde(deserialize_with = "serde::deserialize_vec")] 16 | pub strings: Vec, 17 | } 18 | 19 | #[derive(Debug, Deserialize)] 20 | #[serde(rename_all = "PascalCase")] 21 | pub struct PubsubPeersResponse { 22 | #[serde(deserialize_with = "serde::deserialize_vec")] 23 | pub strings: Vec, 24 | } 25 | 26 | pub type PubsubPubResponse = (); 27 | 28 | #[derive(Debug, Deserialize)] 29 | pub struct PubsubSubResponse { 30 | pub from: String, 31 | 32 | #[serde(deserialize_with = "serde::deserialize_data_field")] 33 | pub data: Vec, 34 | 35 | #[serde(deserialize_with = "serde::deserialize_seqno_field")] 36 | pub seqno: u64, 37 | 38 | #[serde( 39 | rename = "topicIDs", 40 | deserialize_with = "serde::deserialize_topic_field" 41 | )] 42 | pub topic_ids: Vec, 43 | } 44 | 45 | #[cfg(test)] 46 | mod tests { 47 | deserialize_test!(v0_pubsub_ls_0, PubsubLsResponse); 48 | deserialize_test!(v0_pubsub_ls_1, PubsubLsResponse); 49 | deserialize_test!(v0_pubsub_peers_0, PubsubPeersResponse); 50 | deserialize_test!(v0_pubsub_sub_0, PubsubSubResponse); 51 | deserialize_test!(v0_pubsub_sub_1, PubsubSubResponse); 52 | } 53 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/refs.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::serde::Deserialize; 10 | 11 | #[derive(Debug, Deserialize)] 12 | #[serde(rename_all = "PascalCase")] 13 | pub struct RefsLocalResponse { 14 | #[serde(rename = "Ref")] 15 | pub reference: String, 16 | 17 | pub err: String, 18 | } 19 | 20 | #[cfg(test)] 21 | mod tests { 22 | deserialize_test!(v0_refs_local_0, RefsLocalResponse); 23 | } 24 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/repo.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::response::serde; 10 | use crate::serde::Deserialize; 11 | use std::collections::HashMap; 12 | 13 | #[derive(Deserialize)] 14 | #[serde(rename_all = "PascalCase")] 15 | pub struct RepoFsckResponse { 16 | pub message: String, 17 | } 18 | 19 | #[derive(Deserialize)] 20 | #[serde(rename_all = "PascalCase")] 21 | pub struct RepoGcResponse { 22 | #[serde(deserialize_with = "serde::deserialize_hashmap")] 23 | pub key: HashMap, 24 | pub error: Option, 25 | } 26 | 27 | #[derive(Debug, Deserialize)] 28 | #[serde(rename_all = "PascalCase")] 29 | pub struct RepoStatResponse { 30 | pub num_objects: u64, 31 | pub repo_size: u64, 32 | pub repo_path: String, 33 | pub version: String, 34 | } 35 | 36 | // Defined in go-ipfs:master core/commands/repo.go 37 | #[derive(Deserialize)] 38 | #[serde(rename_all = "PascalCase")] 39 | pub struct RepoVerifyResponse { 40 | pub message: String, 41 | // Could technically be an i64 but this is probably safest? 42 | pub progress: i32, 43 | } 44 | 45 | #[derive(Deserialize)] 46 | #[serde(rename_all = "PascalCase")] 47 | pub struct RepoVersionResponse { 48 | pub version: String, 49 | } 50 | 51 | #[cfg(test)] 52 | mod tests { 53 | deserialize_test!(v0_repo_gc_0, RepoGcResponse); 54 | deserialize_test!(v0_repo_stat_0, RepoStatResponse); 55 | deserialize_test!(v0_repo_verify_0, RepoVerifyResponse); 56 | deserialize_test!(v0_repo_verify_1, RepoVerifyResponse); 57 | deserialize_test!(v0_repo_version_0, RepoVersionResponse); 58 | } 59 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/resolve.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::serde::Deserialize; 10 | 11 | #[derive(Deserialize)] 12 | #[serde(rename_all = "PascalCase")] 13 | pub struct ResolveResponse { 14 | pub path: String, 15 | } 16 | 17 | #[cfg(test)] 18 | mod tests { 19 | deserialize_test!(v0_resolve_0, ResolveResponse); 20 | } 21 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/shutdown.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | pub type ShutdownResponse = (); 10 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/stats.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::response::{BitswapStatResponse, RepoStatResponse}; 10 | use crate::serde::Deserialize; 11 | 12 | pub type StatsBitswapResponse = BitswapStatResponse; 13 | 14 | #[derive(Debug, Deserialize)] 15 | #[serde(rename_all = "PascalCase")] 16 | pub struct StatsBwResponse { 17 | pub total_in: u64, 18 | pub total_out: u64, 19 | pub rate_in: f64, 20 | pub rate_out: f64, 21 | } 22 | 23 | pub type StatsRepoResponse = RepoStatResponse; 24 | 25 | #[cfg(test)] 26 | mod tests { 27 | deserialize_test!(v0_stats_bw_0, StatsBwResponse); 28 | } 29 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/swarm.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::response::serde; 10 | use crate::serde::Deserialize; 11 | 12 | #[derive(Debug, Deserialize)] 13 | #[serde(rename_all = "PascalCase")] 14 | pub struct SwarmAddrsLocalResponse { 15 | #[serde(deserialize_with = "serde::deserialize_vec")] 16 | pub strings: Vec, 17 | } 18 | 19 | #[derive(Deserialize)] 20 | #[serde(rename_all = "PascalCase")] 21 | pub struct SwarmAddrsConnectResponse { 22 | #[serde(deserialize_with = "serde::deserialize_vec")] 23 | pub strings: Vec, 24 | } 25 | 26 | #[derive(Deserialize)] 27 | #[serde(rename_all = "PascalCase")] 28 | pub struct SwarmAddrsDisconnectResponse { 29 | #[serde(deserialize_with = "serde::deserialize_vec")] 30 | pub strings: Vec, 31 | } 32 | 33 | #[derive(Deserialize)] 34 | #[serde(rename_all = "PascalCase")] 35 | pub struct SwarmFiltersAddResponse { 36 | #[serde(deserialize_with = "serde::deserialize_vec")] 37 | pub strings: Vec, 38 | } 39 | 40 | #[derive(Deserialize)] 41 | #[serde(rename_all = "PascalCase")] 42 | pub struct SwarmFiltersRmResponse { 43 | #[serde(deserialize_with = "serde::deserialize_vec")] 44 | pub strings: Vec, 45 | } 46 | 47 | #[derive(Debug, Deserialize)] 48 | #[serde(rename_all = "PascalCase")] 49 | pub struct SwarmPeerStream { 50 | pub protocol: String, 51 | } 52 | 53 | #[derive(Debug, Deserialize)] 54 | #[serde(rename_all = "PascalCase")] 55 | pub struct SwarmPeer { 56 | pub addr: String, 57 | pub peer: String, 58 | pub latency: String, 59 | pub muxer: String, 60 | 61 | #[serde(deserialize_with = "serde::deserialize_vec")] 62 | pub streams: Vec, 63 | } 64 | 65 | #[derive(Debug, Deserialize)] 66 | #[serde(rename_all = "PascalCase")] 67 | pub struct SwarmPeersResponse { 68 | #[serde(deserialize_with = "serde::deserialize_vec")] 69 | pub peers: Vec, 70 | } 71 | 72 | #[cfg(test)] 73 | mod tests { 74 | deserialize_test!(v0_swarm_addrs_local_0, SwarmAddrsLocalResponse); 75 | deserialize_test!(v0_swarm_peers_0, SwarmPeersResponse); 76 | deserialize_test!(v0_swarm_peers_1, SwarmPeersResponse); 77 | deserialize_test!(v0_swarm_peers_2, SwarmPeersResponse); 78 | } 79 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/swarm_connect.rs: -------------------------------------------------------------------------------- 1 | use crate::response::serde; 2 | use crate::serde::Deserialize; 3 | 4 | #[derive(Debug, Deserialize)] 5 | #[serde(rename_all = "PascalCase")] 6 | pub struct SwarmConnectResponse { 7 | #[serde(deserialize_with = "serde::deserialize_vec")] 8 | pub strings: Vec, 9 | } 10 | 11 | #[cfg(test)] 12 | mod tests { 13 | deserialize_test!(v0_swarm_connect_0, SwarmConnectResponse); 14 | } 15 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tar.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::serde::Deserialize; 10 | 11 | #[derive(Debug, Deserialize)] 12 | #[serde(rename_all = "PascalCase")] 13 | pub struct TarAddResponse { 14 | pub name: String, 15 | pub hash: String, 16 | } 17 | 18 | #[cfg(test)] 19 | mod tests { 20 | deserialize_test!(v0_tar_add_0, TarAddResponse); 21 | } 22 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_block_stat_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Key": "QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB", 3 | "Size": 1102 4 | } 5 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_bootstrap_list_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Peers": [ 3 | "/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", 4 | "/ip4/104.236.176.52/tcp/4001/ipfs/QmSoLnSGccFuZQJzRadHn95W2CrSFmZuTdDWP8HXaHca9z", 5 | "/ip4/104.236.179.241/tcp/4001/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM", 6 | "/ip4/162.243.248.213/tcp/4001/ipfs/QmSoLueR4xBeUbY9WZ9xGUUxunbKWcrNFTDAadQJmocnWm", 7 | "/ip4/128.199.219.111/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu", 8 | "/ip4/104.236.76.40/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64", 9 | "/ip4/178.62.158.247/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd", 10 | "/ip4/178.62.61.185/tcp/4001/ipfs/QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3", 11 | "/ip4/104.236.151.122/tcp/4001/ipfs/QmSoLju6m7xTh3DuokvT3886QRYqxAzb1kShaanJgW36yx", 12 | "/ip6/2604:a880:1:20::1f9:9001/tcp/4001/ipfs/QmSoLnSGccFuZQJzRadHn95W2CrSFmZuTdDWP8HXaHca9z", 13 | "/ip6/2604:a880:1:20::203:d001/tcp/4001/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM", 14 | "/ip6/2604:a880:0:1010::23:d001/tcp/4001/ipfs/QmSoLueR4xBeUbY9WZ9xGUUxunbKWcrNFTDAadQJmocnWm", 15 | "/ip6/2400:6180:0:d0::151:6001/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu", 16 | "/ip6/2604:a880:800:10::4a:5001/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64", 17 | "/ip6/2a03:b0c0:0:1010::23:1001/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd", 18 | "/ip6/2a03:b0c0:1:d0::e7:1/tcp/4001/ipfs/QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3", 19 | "/ip6/2604:a880:1:20::1d9:6001/tcp/4001/ipfs/QmSoLju6m7xTh3DuokvT3886QRYqxAzb1kShaanJgW36yx" 20 | ] 21 | } 22 | 23 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_dag_get_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": null, 3 | "links": [ 4 | { 5 | "Name": "yellow-pearl.pdf", 6 | "Size": 93263014, 7 | "Cid": { 8 | "/": "QmfDTYvLJ55nPN5WF9QQNbvfBy6c688eUakzXcwBPfT5cp" 9 | } 10 | }, 11 | { 12 | "Name": "yoojin-grace-wuertz-mother-tongue.pdf", 13 | "Size": 207474, 14 | "Cid": { 15 | "/": "QmciFb6GbdL9rzMV7TA6wcxuytHA8rWT7bHNVBW7aMiokn" 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_file_ls_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Arguments": { 3 | "/ipfs/QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG": "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG" 4 | }, 5 | "Objects": { 6 | "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG": { 7 | "Hash": "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG", 8 | "Size": 0, 9 | "Type": "Directory", 10 | "Links": [ 11 | { 12 | "Name": "about", 13 | "Hash": "QmZTR5bcpQD7cFgTorqxZDYaew1Wqgfbd2ud9QqGPAkK2V", 14 | "Size": 1677, 15 | "Type": "File" 16 | }, 17 | { 18 | "Name": "contact", 19 | "Hash": "QmYCvbfNbCwFR45HiNP45rwJgvatpiW38D961L5qAhUM5Y", 20 | "Size": 189, 21 | "Type": "File" 22 | }, 23 | { 24 | "Name": "help", 25 | "Hash": "QmY5heUM5qgRubMDD1og9fhCPA6QdkMp3QCwd4s7gJsyE7", 26 | "Size": 311, 27 | "Type": "File" 28 | }, 29 | { 30 | "Name": "quick-start", 31 | "Hash": "QmdncfsVm2h5Kqq9hPmU7oAVX2zTSVP3L869tgTbPYnsha", 32 | "Size": 1717, 33 | "Type": "File" 34 | }, 35 | { 36 | "Name": "readme", 37 | "Hash": "QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB", 38 | "Size": 1091, 39 | "Type": "File" 40 | }, 41 | { 42 | "Name": "security-notes", 43 | "Hash": "QmTumTjvcYCAvRRwQ8sDRxh8ezmrcr88YFU7iYNroGGTBZ", 44 | "Size": 1016, 45 | "Type": "File" 46 | } 47 | ] 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_file_ls_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "Arguments": null, 3 | "Objects": null 4 | } 5 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_files_ls_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Entries": null 3 | } 4 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_files_stat_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Hash": "QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn", 3 | "Size": 0, 4 | "CumulativeSize": 4, 5 | "Blocks": 0, 6 | "Type": "directory" 7 | } 8 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_id_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "ID": "12D3KooWFX2LDeiJu29PWiVk1Wn5h11czSXjtbZuxwTpvA1Ui1Gt", 3 | "PublicKey": "CAESIFS00YT+YVGn4fxI4Bmc0PrvP1JIzhgsD5O8rMQ3Mlxx", 4 | "Addresses": [ 5 | "/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWFX2LDeiJu29PWiVk1Wn5h11czSXjtbZuxwTpvA1Ui1Gt", 6 | "/ip4/127.0.0.1/udp/4001/quic-v1/p2p/12D3KooWFX2LDeiJu29PWiVk1Wn5h11czSXjtbZuxwTpvA1Ui1Gt", 7 | "/ip4/127.0.0.1/udp/4001/quic-v1/webtransport/certhash/uEiB3d2P2cOsDRwxmoDk6bZ1HS8PD5oCHTCA56Iss6_80SQ/certhash/uEiBNlsbe3IxJNYZuT1x7Nz8nTB1Y-0KvODqUnmdTCWqWLA/p2p/12D3KooWFX2LDeiJu29PWiVk1Wn5h11czSXjtbZuxwTpvA1Ui1Gt", 8 | "/ip4/127.0.0.1/udp/4001/quic/p2p/12D3KooWFX2LDeiJu29PWiVk1Wn5h11czSXjtbZuxwTpvA1Ui1Gt", 9 | "/ip4/104.131.131.82/tcp/4001/p2p/12D3KooWJmT7tEPitk67Vem6T5zCGqkVZZVX377XtXPWPLryyDvp/p2p-circuit/p2p/12D3KooWFX2LDeiJu29PWiVk1Wn5h11czSXjtbZuxwTpvA1Ui1Gt", 10 | "/ip4/104.131.131.82/udp/4001/quic-v1/p2p/12D3KooWJmT7tEPitk67Vem6T5zCGqkVZZVX377XtXPWPLryyDvp/p2p-circuit/p2p/12D3KooWFX2LDeiJu29PWiVk1Wn5h11czSXjtbZuxwTpvA1Ui1Gt", 11 | "/ip4/104.131.131.82/udp/4001/quic/p2p/12D3KooWJmT7tEPitk67Vem6T5zCGqkVZZVX377XtXPWPLryyDvp/p2p-circuit/p2p/12D3KooWFX2LDeiJu29PWiVk1Wn5h11czSXjtbZuxwTpvA1Ui1Gt", 12 | "/ip4/172.20.0.2/tcp/4001/p2p/12D3KooWFX2LDeiJu29PWiVk1Wn5h11czSXjtbZuxwTpvA1Ui1Gt", 13 | "/ip4/172.20.0.2/udp/4001/quic-v1/p2p/12D3KooWFX2LDeiJu29PWiVk1Wn5h11czSXjtbZuxwTpvA1Ui1Gt", 14 | "/ip4/172.20.0.2/udp/4001/quic-v1/webtransport/certhash/uEiB3d2P2cOsDRwxmoDk6bZ1HS8PD5oCHTCA56Iss6_80SQ/certhash/uEiBNlsbe3IxJNYZuT1x7Nz8nTB1Y-0KvODqUnmdTCWqWLA/p2p/12D3KooWFX2LDeiJu29PWiVk1Wn5h11czSXjtbZuxwTpvA1Ui1Gt", 15 | "/ip4/172.20.0.2/udp/4001/quic/p2p/12D3KooWFX2LDeiJu29PWiVk1Wn5h11czSXjtbZuxwTpvA1Ui1Gt" 16 | ], 17 | "AgentVersion": "kubo/0.22.0/3f884d3/docker", 18 | "Protocols": [ 19 | "/ipfs/bitswap", 20 | "/ipfs/bitswap/1.0.0", 21 | "/ipfs/bitswap/1.1.0", 22 | "/ipfs/bitswap/1.2.0", 23 | "/ipfs/id/1.0.0", 24 | "/ipfs/id/push/1.0.0", 25 | "/ipfs/lan/kad/1.0.0", 26 | "/ipfs/ping/1.0.0", 27 | "/libp2p/circuit/relay/0.2.0/stop", 28 | "/libp2p/dcutr", 29 | "/x/" 30 | ] 31 | } -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_key_gen_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "test2", 3 | "Id": "QmXyKWg9HzHer8YKyBVs7iwQbMnxTDMQxPFZCJVfhgW2gF" 4 | } 5 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_key_list_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Keys": [ 3 | { 4 | "Name": "self", 5 | "Id": "QmSf2fesXJ9t7Vz91t5Ryhb6NmyXiZ6y9nddCeRgauKCCz" 6 | }, 7 | { 8 | "Name": "test", 9 | "Id": "QmXnVxhRRiQ5UTb6vkeTcP2AKA2NetyYsNksnp46or6gAT" 10 | }, 11 | { 12 | "Name": "test2", 13 | "Id": "QmXyKWg9HzHer8YKyBVs7iwQbMnxTDMQxPFZCJVfhgW2gF" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_key_rename_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Was":"test0", 3 | "Now":"test", 4 | "Id":"QmPLabRUDjgGUmLTQwbBzbFtRGH3jaC33jbHKBtyQ7TfrC", 5 | "Overwrite":false 6 | } 7 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_key_rm_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Keys": [ 3 | { 4 | "Name":"test", 5 | "Id":"QmPLabRUDjgGUmLTQwbBzbFtRGH3jaC33jbHKBtyQ7TfrC" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_log_ls_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Strings": [ 3 | "engine", 4 | "bitswap_network", 5 | "commands/cli", 6 | "relay", 7 | "core/server", 8 | "tcp-tpt", 9 | "lock", 10 | "fsrepo", 11 | "transport", 12 | "secio", 13 | "conn", 14 | "pin", 15 | "ping", 16 | "gc", 17 | "routing/record", 18 | "core", 19 | "coreunix", 20 | "metrics-prometheus", 21 | "reuseport-poll", 22 | "blockservice", 23 | "mdns", 24 | "floodsub", 25 | "net/identify", 26 | "basichost", 27 | "filestore", 28 | "mfs", 29 | "ipns-repub", 30 | "multiplex", 31 | "providers", 32 | "peerqueue", 33 | "commands/http", 34 | "mocknet", 35 | "bitswap", 36 | "ipfsaddr", 37 | "chunk", 38 | "table", 39 | "peer", 40 | "mockrouter", 41 | "addrutil", 42 | "node", 43 | "corerepo", 44 | "plugin/loader", 45 | "path", 46 | "routedhost", 47 | "reprovider", 48 | "dht", 49 | "command", 50 | "fuse/ipfs", 51 | "supernode/proxy", 52 | "cmd/ipfs", 53 | "eventlog", 54 | "fuse/ipns", 55 | "cmds/files", 56 | "tarfmt", 57 | "nat", 58 | "bstestnet", 59 | "mount", 60 | "namesys", 61 | "peerstore", 62 | "connmgr", 63 | "boguskey", 64 | "dht.pb", 65 | "flatfs", 66 | "blockstore", 67 | "swarm2", 68 | "core/commands", 69 | "supernode" 70 | ] 71 | } 72 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_ls_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Objects": [ 3 | { 4 | "Hash": "/ipns/ipfs.io/", 5 | "Links": [ 6 | { 7 | "Name": "author", 8 | "Hash": "QmRouqeAuSRHuAhgksVGyj5bHwoaGCeHvrucvZHjLycRge", 9 | "Size": 59289, 10 | "Type": 1 11 | }, 12 | { 13 | "Name": "contact-ipfs", 14 | "Hash": "QmSbkzhqyXfLvKtgRppMc7FVJC3m7tbchrqXtYeSh54jBe", 15 | "Size": 5847, 16 | "Type": 1 17 | }, 18 | { 19 | "Name": "css", 20 | "Hash": "QmRNaib6Pz2PUVLpEbMkEdETu5cup77Dtkief58o4NRPaM", 21 | "Size": 42684, 22 | "Type": 1 23 | }, 24 | { 25 | "Name": "docs", 26 | "Hash": "QmTG4WSv8bL4JMqbeYmzGGo8k75zx73Cz3uzLnGMV6oLmE", 27 | "Size": 254520, 28 | "Type": 1 29 | }, 30 | { 31 | "Name": "fonts", 32 | "Hash": "QmX7GQcyrVaKnS24y6nvU4LEB9hkcK5TkxoxRBaGFUUD6Q", 33 | "Size": 914365, 34 | "Type": 1 35 | }, 36 | { 37 | "Name": "images", 38 | "Hash": "QmZMWv34NMLbhBxWysqViFdiMkGf4WtfXc5GQDnV8NWo5J", 39 | "Size": 1509477, 40 | "Type": 1 41 | }, 42 | { 43 | "Name": "index.html", 44 | "Hash": "QmbsAqjLSQJ76TCAB6YwBpktTdUP3B9adkU4XtSsTuHpSs", 45 | "Size": 17226, 46 | "Type": 2 47 | }, 48 | { 49 | "Name": "js", 50 | "Hash": "QmbbctxCiwug9dYiRgbi1kdJGxht7wELYtgx2Lh7LjtpLK", 51 | "Size": 753757, 52 | "Type": 1 53 | }, 54 | { 55 | "Name": "legal", 56 | "Hash": "QmSvqDBPaEk6CSAU1sZW4ve2Vgmb9FdM2BvVKvNsChLnbt", 57 | "Size": 5759, 58 | "Type": 1 59 | }, 60 | { 61 | "Name": "media", 62 | "Hash": "QmZfLAvPwPasDwAH5bC7nChwjSGYGkabZGV4YLfCn8LKwT", 63 | "Size": 12890, 64 | "Type": 1 65 | }, 66 | { 67 | "Name": "sitemap.xml", 68 | "Hash": "QmYBpz8u7FhtwzyeMMq2Qj4PMpPA5e8WTLgUmTrCvNGWoy", 69 | "Size": 4667, 70 | "Type": 2 71 | } 72 | ] 73 | } 74 | ] 75 | } 76 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_ls_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "Objects": [ 3 | { 4 | "Hash": "/ipfs/QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG", 5 | "Links": [ 6 | { 7 | "Name": "about", 8 | "Hash": "QmZTR5bcpQD7cFgTorqxZDYaew1Wqgfbd2ud9QqGPAkK2V", 9 | "Size": 1688, 10 | "Type": 2 11 | }, 12 | { 13 | "Name": "contact", 14 | "Hash": "QmYCvbfNbCwFR45HiNP45rwJgvatpiW38D961L5qAhUM5Y", 15 | "Size": 200, 16 | "Type": 2 17 | }, 18 | { 19 | "Name": "help", 20 | "Hash": "QmY5heUM5qgRubMDD1og9fhCPA6QdkMp3QCwd4s7gJsyE7", 21 | "Size": 322, 22 | "Type": 2 23 | }, 24 | { 25 | "Name": "quick-start", 26 | "Hash": "QmdncfsVm2h5Kqq9hPmU7oAVX2zTSVP3L869tgTbPYnsha", 27 | "Size": 1728, 28 | "Type": 2 29 | }, 30 | { 31 | "Name": "readme", 32 | "Hash": "QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB", 33 | "Size": 1102, 34 | "Type": 2 35 | }, 36 | { 37 | "Name": "security-notes", 38 | "Hash": "QmTumTjvcYCAvRRwQ8sDRxh8ezmrcr88YFU7iYNroGGTBZ", 39 | "Size": 1027, 40 | "Type": 2 41 | } 42 | ] 43 | } 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_mount_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "IPFS": "/home/ftseng/.ipfsmnt/ipfs", 3 | "IPNS": "/home/ftseng/.ipfsmnt/ipns", 4 | "FuseAllowOther": false 5 | } 6 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_name_resolve_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Path": "/ipfs/QmeqJJqSyNKt6d9SFRR1Rec6MNGJX6hdfnhUi2Bphec79Y" 3 | } 4 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_object_diff_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Changes": [ 3 | { 4 | "Type": 2, 5 | "Path": "", 6 | "Before": { 7 | "/": "QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB" 8 | }, 9 | "After": { 10 | "/": "QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB" 11 | } 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_object_links_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Hash": "QmVLDAhCY3X9P2uRudKAryuQFPM5zqA3Yij1dY8FpGbL7T", 3 | "Links": [ 4 | { 5 | "Name": "about", 6 | "Hash": "QmZTR5bcpQD7cFgTorqxZDYaew1Wqgfbd2ud9QqGPAkK2V", 7 | "Size": 1688 8 | }, 9 | { 10 | "Name": "contact", 11 | "Hash": "QmYCvbfNbCwFR45HiNP45rwJgvatpiW38D961L5qAhUM5Y", 12 | "Size": 200 13 | }, 14 | { 15 | "Name": "help", 16 | "Hash": "QmY5heUM5qgRubMDD1og9fhCPA6QdkMp3QCwd4s7gJsyE7", 17 | "Size": 322 18 | }, 19 | { 20 | "Name": "ping", 21 | "Hash": "QmejvEPop4D7YUadeGqYWmZxHhLc4JBUCzJJHWMzdcMe2y", 22 | "Size": 12 23 | }, 24 | { 25 | "Name": "quick-start", 26 | "Hash": "QmdncfsVm2h5Kqq9hPmU7oAVX2zTSVP3L869tgTbPYnsha", 27 | "Size": 1728 28 | }, 29 | { 30 | "Name": "readme", 31 | "Hash": "QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB", 32 | "Size": 1102 33 | }, 34 | { 35 | "Name": "security-notes", 36 | "Hash": "QmQ5vhrL7uv6tuoN9KeVBwd4PwfQkXdVVmDLUZuTNxqgvm", 37 | "Size": 1173 38 | } 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_object_stat_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Hash": "QmVLDAhCY3X9P2uRudKAryuQFPM5zqA3Yij1dY8FpGbL7T", 3 | "NumLinks": 7, 4 | "BlockSize": 355, 5 | "LinksSize": 353, 6 | "DataSize": 2, 7 | "CumulativeSize": 6580 8 | } 9 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_pin_add_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Pins": [ 3 | "QmQ5vhrL7uv6tuoN9KeVBwd4PwfQkXdVVmDLUZuTNxqgvm" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_pin_ls_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Keys": { 3 | "QmQ5vhrL7uv6tuoN9KeVBwd4PwfQkXdVVmDLUZuTNxqgvm": { 4 | "Type": "indirect through QmVLDAhCY3X9P2uRudKAryuQFPM5zqA3Yij1dY8FpGbL7T" 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_ping_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Success": true, 3 | "Time": 0, 4 | "Text": "PING QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ." 5 | } 6 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_ping_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "Success": true, 3 | "Time": 81228717, 4 | "Text": "" 5 | } 6 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_ping_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "Success": true, 3 | "Time": 0, 4 | "Text": "Average latency: 88.31ms" 5 | } 6 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_pubsub_ls_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Strings": null 3 | } 4 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_pubsub_ls_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "Strings": [ 3 | "foo" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_pubsub_peers_0.json: -------------------------------------------------------------------------------- 1 | {"Strings":["QmSoLnSGccFuZQJzRadHn95W2CrSFmZuTdDWP8HXaHca9z","QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64","QmSoLueR4xBeUbY9WZ9xGUUxunbKWcrNFTDAadQJmocnWm","QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd"]} 2 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_pubsub_sub_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "from": "12D3KooWQh2LjxNEcM9tfGU53cCFcQxwNPFCrsWMn4nYMpV8fL2S", 3 | "data": "uIyBpcGZzIGNvbW1hbmRsaW5lIHRvb2wKClRoaXMgaXMgdGhlIFtpcGZzXShodHRwOi8vaXBmcy5pbykgY29tbWFuZGxpbmUgdG9vbC4gSXQgY29udGFpbnMgYSBmdWxsIGlwZnMgbm9kZS4KCiMjIEluc3RhbGwKClRvIGluc3RhbGwgaXQsIG1vdmUgdGhlIGJpbmFyeSBzb21ld2hlcmUgaW4geW91ciBgJFBBVEhgOgoKYGBgc2gKc3VkbyBtdiBpcGZzIC91c3IvbG9jYWwvYmluL2lwZnMKYGBgCgpPciBydW4gYHN1ZG8gLi9pbnN0YWxsLnNoYCB3aGljaCBkb2VzIHRoaXMgZm9yIHlvdS4KCiMjIFVzYWdlCgpGaXJzdCwgeW91IG11c3QgaW5pdGlhbGl6ZSB5b3VyIGxvY2FsIGlwZnMgbm9kZToKCmBgYHNoCmlwZnMgaW5pdApgYGAKClRoaXMgd2lsbCBnaXZlIHlvdSBkaXJlY3Rpb25zIHRvIGdldCBzdGFydGVkIHdpdGggaXBmcy4KWW91IGNhbiBhbHdheXMgZ2V0IGhlbHAgd2l0aDoKCmBgYHNoCmlwZnMgLS1oZWxwCmBgYAo", 4 | "seqno": "uFs7SJ9RokxA", 5 | "topicIDs": [ 6 | "uaGVsbG93b3JsZAo" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_pubsub_sub_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "from": "12D3KooWQh2LjxNEcM9tfGU53cCFcQxwNPFCrsWMn4nYMpV8fL2S", 3 | "data": "uIyBpcGZzIGNvbW1hbmRsaW5lIHRvb2wKClRoaXMgaXMgdGhlIFtpcGZzXShodHRwOi8vaXBmcy5pbykgY29tbWFuZGxpbmUgdG9vbC4gSXQgY29udGFpbnMgYSBmdWxsIGlwZnMgbm9kZS4KCiMjIEluc3RhbGwKClRvIGluc3RhbGwgaXQsIG1vdmUgdGhlIGJpbmFyeSBzb21ld2hlcmUgaW4geW91ciBgJFBBVEhgOgoKYGBgc2gKc3VkbyBtdiBpcGZzIC91c3IvbG9jYWwvYmluL2lwZnMKYGBgCgpPciBydW4gYHN1ZG8gLi9pbnN0YWxsLnNoYCB3aGljaCBkb2VzIHRoaXMgZm9yIHlvdS4KCiMjIFVzYWdlCgpGaXJzdCwgeW91IG11c3QgaW5pdGlhbGl6ZSB5b3VyIGxvY2FsIGlwZnMgbm9kZToKCmBgYHNoCmlwZnMgaW5pdApgYGAKClRoaXMgd2lsbCBnaXZlIHlvdSBkaXJlY3Rpb25zIHRvIGdldCBzdGFydGVkIHdpdGggaXBmcy4KWW91IGNhbiBhbHdheXMgZ2V0IGhlbHAgd2l0aDoKCmBgYHNoCmlwZnMgLS1oZWxwCmBgYAo", 4 | "seqno": "uFs7SJ9RokxE", 5 | "topicIDs": [ 6 | "uaGVsbG93b3JsZAo" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_refs_local_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ref": "QmSvqDBPaEk6CSAU1sZW4ve2Vgmb9FdM2BvVKvNsChLnbt", 3 | "Err": "" 4 | } 5 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_repo_gc_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Key": { 3 | "/": "QmSvqDBPaEk6CSAU1sZW4ve2Vgmb9FdM2BvVKvNsChLnbt" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_repo_stat_0.json: -------------------------------------------------------------------------------- 1 | {"NumObjects":13,"RepoSize":27387827,"RepoPath":"/home/ftseng/.ipfs","Version":"fs-repo@6","StorageMax":10000000000} 2 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_repo_verify_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Message": "", 3 | "Progress": 1 4 | } 5 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_repo_verify_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "Message": "verify complete, all blocks validated.", 3 | "Progress": 0 4 | } 5 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_repo_version_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "6" 3 | } 4 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_resolve_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Path": "/ipfs/QmZfLAvPwPasDwAH5bC7nChwjSGYGkabZGV4YLfCn8LKwT" 3 | } 4 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_stats_bw_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "TotalIn": 13869129, 3 | "TotalOut": 8120401, 4 | "RateIn": 191.88670148419368, 5 | "RateOut": 13.787621471639223 6 | } 7 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_swarm_addrs_local_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Strings": [ 3 | "/ip4/127.0.0.1/tcp/4001", 4 | "/ip4/192.168.1.185/tcp/4001", 5 | "/ip4/98.115.121.45/tcp/4001", 6 | "/ip6/::1/tcp/4001" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_swarm_connect_0.json: -------------------------------------------------------------------------------- 1 | {"Strings":["connect 12D3KooWQ2hL9NschcJ1Suqa1TybJc2ZaacqoQMBT3ziFC7Ye2BZ success"]} -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_swarm_peers_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Peers": [ 3 | { 4 | "Addr": "/ip4/104.236.151.122/tcp/4001", 5 | "Peer": "QmSoLju6m7xTh3DuokvT3886QRYqxAzb1kShaanJgW36yx", 6 | "Latency": "", 7 | "Muxer": "*sm_yamux.conn", 8 | "Streams": null 9 | }, 10 | { 11 | "Addr": "/ip4/104.236.76.40/tcp/4001", 12 | "Peer": "QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64", 13 | "Latency": "", 14 | "Muxer": "*sm_yamux.conn", 15 | "Streams": null 16 | }, 17 | { 18 | "Addr": "/ip4/146.185.156.246/tcp/4001", 19 | "Peer": "QmdxtNRkqspKXWnNZh95sfK74PuKecLrG4wNKHwcjaYEv8", 20 | "Latency": "", 21 | "Muxer": "*sm_yamux.conn", 22 | "Streams": null 23 | }, 24 | { 25 | "Addr": "/ip4/162.243.248.213/tcp/4001", 26 | "Peer": "QmSoLueR4xBeUbY9WZ9xGUUxunbKWcrNFTDAadQJmocnWm", 27 | "Latency": "", 28 | "Muxer": "*sm_yamux.conn", 29 | "Streams": null 30 | }, 31 | { 32 | "Addr": "/ip4/178.62.61.185/tcp/4001", 33 | "Peer": "QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3", 34 | "Latency": "", 35 | "Muxer": "*sm_yamux.conn", 36 | "Streams": null 37 | }, 38 | { 39 | "Addr": "/ip4/188.40.114.11/tcp/4001", 40 | "Peer": "QmZY7MtK8ZbG1suwrxc7xEYZ2hQLf1dAWPRHhjxC8rjq8E", 41 | "Latency": "", 42 | "Muxer": "*sm_yamux.conn", 43 | "Streams": null 44 | }, 45 | { 46 | "Addr": "/ip4/192.241.220.29/tcp/4001", 47 | "Peer": "QmYbAMm8nFi6Rhm5ciwT4vZGKM4v4Kf9pUtTuoDmCcJAkU", 48 | "Latency": "", 49 | "Muxer": "*sm_yamux.conn", 50 | "Streams": null 51 | }, 52 | { 53 | "Addr": "/ip4/194.254.61.213/tcp/4001", 54 | "Peer": "QmXtyRJmYkpKM3vJ5dWj7JpPKBHHUZS4aWGX9RFeg4v8WQ", 55 | "Latency": "", 56 | "Muxer": "*sm_yamux.conn", 57 | "Streams": null 58 | }, 59 | { 60 | "Addr": "/ip4/31.172.137.10/tcp/13727", 61 | "Peer": "QmYLNAbh1PmttVgYRnjbKZM7ukwqquMquejFN9D5mzaTQa", 62 | "Latency": "", 63 | "Muxer": "*sm_yamux.conn", 64 | "Streams": null 65 | }, 66 | { 67 | "Addr": "/ip4/43.229.62.238/tcp/4001", 68 | "Peer": "QmRCCsK6Zkd8PjMGD8MyoM14j76sTDonHRM6uv6NBg27hF", 69 | "Latency": "", 70 | "Muxer": "*sm_yamux.conn", 71 | "Streams": null 72 | }, 73 | { 74 | "Addr": "/ip4/81.4.120.158/tcp/4001", 75 | "Peer": "QmQ9W8XbGf7bocnDMPXaQGTrKC8hjUL1Sh2vrhTYGqoo9Y", 76 | "Latency": "", 77 | "Muxer": "*sm_yamux.conn", 78 | "Streams": null 79 | }, 80 | { 81 | "Addr": "/ip4/98.214.191.195/tcp/60389", 82 | "Peer": "QmNU6sCSZ88ukfCV5dBWvgjjrerki7DQdvtnpFCG7oEmg5", 83 | "Latency": "", 84 | "Muxer": "*sm_yamux.conn", 85 | "Streams": null 86 | } 87 | ] 88 | } 89 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_swarm_peers_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "Peers": [ 3 | { 4 | "Addr": "/ip4/35.167.26.28/tcp/4001", 5 | "Peer": "QmNRuQrwtGgeVQgndTny4A4Rukg7GR7vzDJrVJxUBfqevk", 6 | "Latency": "393.975341ms", 7 | "Muxer": "*sm_yamux.conn", 8 | "Streams": [ 9 | { 10 | "Protocol": "" 11 | }, 12 | { 13 | "Protocol": "/ipfs/bitswap" 14 | } 15 | ] 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_swarm_peers_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "Peers": [ 3 | { 4 | "Addr": "/ip4/104.131.131.82/tcp/4001", 5 | "Peer": "QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", 6 | "Latency": "821.60077ms", 7 | "Muxer": "*sm_yamux.conn", 8 | "Streams": null 9 | }, 10 | { 11 | "Addr": "/ip4/104.236.151.122/tcp/4001", 12 | "Peer": "QmSoLju6m7xTh3DuokvT3886QRYqxAzb1kShaanJgW36yx", 13 | "Latency": "205.432977ms", 14 | "Muxer": "*sm_yamux.conn", 15 | "Streams": null 16 | }, 17 | { 18 | "Addr": "/ip4/178.62.61.185/tcp/4001", 19 | "Peer": "QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3", 20 | "Latency": "1.744576368s", 21 | "Muxer": "*sm_yamux.conn", 22 | "Streams": null 23 | }, 24 | { 25 | "Addr": "/ip4/35.167.26.28/tcp/4001", 26 | "Peer": "QmNRuQrwtGgeVQgndTny4A4Rukg7GR7vzDJrVJxUBfqevk", 27 | "Latency": "393.975341ms", 28 | "Muxer": "*sm_yamux.conn", 29 | "Streams": null 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_tar_add_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "test.tar", 3 | "Hash": "QmSJ3UjnffgzAc5Fnnw4tojjhk6mhkV77eoxMYJZ5DWZ98", 4 | "Size": "3083" 5 | } 6 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_version_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "0.4.11", 3 | "Commit": "", 4 | "Repo": "6", 5 | "System": "amd64/linux", 6 | "Golang": "go1.9" 7 | } 8 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/tests/v0_version_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "0.4.11", 3 | "Commit": "", 4 | "Repo": "6" 5 | } 6 | -------------------------------------------------------------------------------- /ipfs-api-prelude/src/response/version.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | use crate::serde::Deserialize; 10 | 11 | #[derive(Debug, Deserialize)] 12 | #[serde(rename_all = "PascalCase")] 13 | pub struct VersionResponse { 14 | pub version: String, 15 | pub commit: String, 16 | pub repo: String, 17 | 18 | // Not declared in the IPFS interface spec. 19 | pub system: Option, 20 | 21 | // Only for the Go implementation of IPFS. 22 | pub golang: Option, 23 | } 24 | 25 | #[cfg(test)] 26 | mod tests { 27 | deserialize_test!(v0_version_0, VersionResponse); 28 | deserialize_test!(v0_version_1, VersionResponse); 29 | } 30 | -------------------------------------------------------------------------------- /ipfs-api-versions/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | description = "Test support crate defining which IPFS versions are tested against" 3 | edition = "2021" 4 | license = "MIT OR Apache-2.0" 5 | name = "ipfs-api-versions" 6 | documentation = "https://docs.rs/ipfs-api" 7 | readme = "../README.md" 8 | repository = "https://github.com/ferristseng/rust-ipfs-api" 9 | version = "0.1.0" 10 | 11 | [lib] 12 | proc-macro = true 13 | 14 | [dependencies] 15 | proc-macro2 = "1.0" 16 | quote = "1.0" 17 | 18 | [dev-dependencies] 19 | test-case = "3.1" 20 | -------------------------------------------------------------------------------- /ipfs-api-versions/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | 8 | //! Define which IPFS (Kubo) Docker images the Rust library will be tested against. 9 | //! 10 | //! # Examples 11 | //! 12 | //! ```rust 13 | //! use ipfs_api_versions::test_current_image; 14 | //! 15 | //! #[test_current_image] 16 | //! fn test_foo(image_name: &str, image_tag: &str) { 17 | //! // ...test implementation to run against only the latest image 18 | //! } 19 | //! ``` 20 | //! 21 | //! ```rust 22 | //! use ipfs_api_versions::test_supported_images; 23 | //! 24 | //! #[test_supported_images] 25 | //! fn test_bar(image_name: &str, image_tag: &str) { 26 | //! // ...test implementation to run against all supported images 27 | //! } 28 | //! ``` 29 | 30 | use proc_macro::TokenStream as CompilerTokenStream; 31 | use quote::{quote, quote_spanned}; 32 | 33 | /// Docker images of IPFS daemon versions supported by this library, in ascending order. 34 | fn supported() -> Vec<(String, String)> { 35 | let source = [ 36 | ("ipfs/go-ipfs", "v0.7.0"), 37 | ("ipfs/go-ipfs", "v0.8.0"), 38 | ("ipfs/go-ipfs", "v0.9.1"), 39 | ("ipfs/go-ipfs", "v0.10.0"), 40 | ("ipfs/go-ipfs", "v0.11.1"), 41 | ("ipfs/go-ipfs", "v0.12.2"), 42 | ("ipfs/go-ipfs", "v0.13.0"), 43 | ("ipfs/kubo", "v0.14.0"), 44 | ("ipfs/kubo", "v0.15.0"), 45 | ("ipfs/kubo", "v0.16.0"), 46 | ("ipfs/kubo", "v0.17.0"), 47 | ("ipfs/kubo", "v0.18.0"), 48 | ("ipfs/kubo", "v0.19.0"), 49 | ("ipfs/kubo", "v0.20.0"), 50 | ("ipfs/kubo", "v0.21.0"), 51 | ("ipfs/kubo", "v0.22.0"), 52 | ]; 53 | 54 | source 55 | .into_iter() 56 | .map(|(i, t)| (i.into(), t.into())) 57 | .collect() 58 | } 59 | 60 | /// Docker image of most recent supported IPFS daemon. 61 | fn current() -> (String, String) { 62 | supported().into_iter().last().unwrap() 63 | } 64 | 65 | fn image_test_case(image_name: &str, image_tag: &str) -> proc_macro2::TokenStream { 66 | quote! { 67 | #[test_case::test_case(#image_name, #image_tag)] 68 | } 69 | } 70 | 71 | fn unexpected_meta(meta: CompilerTokenStream) -> Option { 72 | let m2: proc_macro2::TokenStream = meta.into(); 73 | 74 | if let Some(m) = m2.into_iter().next() { 75 | let result = quote_spanned! { m.span() => 76 | compile_error!("Macro does not expect any arguments."); 77 | }; 78 | 79 | Some(result.into()) 80 | } else { 81 | None 82 | } 83 | } 84 | 85 | #[proc_macro_attribute] 86 | pub fn test_current_image( 87 | meta: CompilerTokenStream, 88 | input: CompilerTokenStream, 89 | ) -> CompilerTokenStream { 90 | if let Some(err) = unexpected_meta(meta) { 91 | err 92 | } else { 93 | let (image_name, image_tag) = current(); 94 | 95 | let tokens = vec![image_test_case(&image_name, &image_tag), input.into()]; 96 | 97 | let result = quote! { 98 | #(#tokens)* 99 | }; 100 | 101 | result.into() 102 | } 103 | } 104 | 105 | #[proc_macro_attribute] 106 | pub fn test_supported_images( 107 | meta: CompilerTokenStream, 108 | input: CompilerTokenStream, 109 | ) -> CompilerTokenStream { 110 | if let Some(err) = unexpected_meta(meta) { 111 | err 112 | } else { 113 | let mut tokens: Vec<_> = supported() 114 | .iter() 115 | .map(|(image_name, image_tag)| { 116 | quote! { 117 | #[test_case::test_case(#image_name, #image_tag)] 118 | } 119 | }) 120 | .collect(); 121 | 122 | tokens.push(input.into()); 123 | 124 | let result = quote! { 125 | #(#tokens)* 126 | }; 127 | 128 | result.into() 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /ipfs-api/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ipfs-api" 3 | description = "Implementation of an IPFS HTTP API client" 4 | authors = ["Ferris Tseng "] 5 | edition = "2021" 6 | documentation = "https://docs.rs/ipfs-api" 7 | repository = "https://github.com/ferristseng/rust-ipfs-api" 8 | keywords = ["ipfs"] 9 | categories = ["filesystem", "web-programming"] 10 | version = "0.17.0" 11 | readme = "../README.md" 12 | license = "MIT OR Apache-2.0" 13 | 14 | [badges] 15 | github = { repository = "ferristseng/rust-ipfs-api", workflow = "Rust" } 16 | maintenance = { status = "deprecated" } 17 | 18 | [features] 19 | default = ["with-hyper"] 20 | with-hyper-tls = ["with-hyper", "ipfs-api-backend-hyper/with-hyper-tls"] 21 | with-hyper-rustls = ["with-hyper", "ipfs-api-backend-hyper/with-hyper-rustls"] 22 | with-hyper = ["ipfs-api-backend-hyper", "ipfs-api-backend-hyper/with-builder"] 23 | with-actix = ["ipfs-api-backend-actix", "ipfs-api-backend-actix/with-builder"] 24 | 25 | [dependencies] 26 | ipfs-api-backend-actix = { version = "0.7", path = "../ipfs-api-backend-actix", optional = true } 27 | ipfs-api-backend-hyper = { version = "0.6", path = "../ipfs-api-backend-hyper", optional = true } 28 | 29 | [dev-dependencies] 30 | actix-rt = "2.5" 31 | cfg-if = "1" 32 | futures = "0.3" 33 | ipfs-api-versions = { version = "0.1", path = "../ipfs-api-versions" } 34 | passivized_docker_engine_client = "0.0.8" 35 | passivized_htpasswd = "0.0.5" 36 | reqwest = "0.11" 37 | tempfile = "3.3" 38 | test-case = "2.2" 39 | thiserror = "1.0" 40 | tokio = { version = "1", features = ["fs", "rt-multi-thread", "macros"] } 41 | 42 | # Only when testing with-hyper 43 | hyper = "0.14" 44 | 45 | # Only when testing with-hyper-tls 46 | hyper-tls = "0.5" 47 | -------------------------------------------------------------------------------- /ipfs-api/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | // 8 | 9 | //! Rust library for connecting to the IPFS HTTP API using Hyper/Actix. 10 | //! 11 | //! ## Usage 12 | //! 13 | //! ### Using Hyper 14 | //! 15 | //! To use the Hyper backend, declare: 16 | //! 17 | //! ```toml 18 | //! [dependencies] 19 | //! ipfs-api-backend-hyper = "0.6" 20 | //! ``` 21 | //! 22 | //! You can specify either `with-hyper-rustls` or `with-hyper-tls` (mutually exclusive) feature for TLS support. 23 | //! 24 | //! ### Using Actix 25 | //! 26 | //! To use the Actix backend, declare: 27 | //! 28 | //! ```toml 29 | //! [dependencies] 30 | //! ipfs-api-backend-actix = "0.7" 31 | //! ``` 32 | //! 33 | //! ### Builder Pattern 34 | //! 35 | //! With either the Hyper or Actix backend, you can specify the `with-builder` feature to enable a builder pattern to use when building requests. 36 | //! 37 | //! ## Usage (DEPRECATED) 38 | //! 39 | //! ```toml 40 | //! [dependencies] 41 | //! ipfs-api = "0.17.0" 42 | //! ``` 43 | //! 44 | //! ### Feature Flags (DEPRECATED) 45 | //! 46 | //! You can use `actix-web` as a backend instead of `hyper`. 47 | //! 48 | //! ```toml 49 | //! [dependencies] 50 | //! ipfs-api = { version = "0.17.0", features = ["with-actix"], default-features = false } 51 | //! ``` 52 | //! 53 | //! You also have the option of using [`rustls`](https://crates.io/crates/rustls) 54 | //! instead of native tls: 55 | //! 56 | //! ```toml 57 | //! [dependencies] 58 | //! ipfs-api = { version = "0.17.0", features = ["with-hyper-rustls"], default-features = false } 59 | //! ``` 60 | //! 61 | //! To enable the builder pattern (default) use the `with-builder` feature: 62 | //! 63 | //! ```toml 64 | //! [dependencies] 65 | //! ipfs-api = { version = "0.17.0", features = ["with-hyper-rustls", "with-builder"], default-features = false } 66 | //! ``` 67 | //! 68 | //! ## Examples 69 | //! 70 | //! ### Writing a file to IPFS 71 | //! 72 | //! #### With Hyper 73 | //! 74 | //! ```no_run 75 | //! use ipfs_api::{IpfsApi, IpfsClient}; 76 | //! use std::io::Cursor; 77 | //! 78 | //! #[tokio::main] 79 | //! async fn main() { 80 | //! let client = IpfsClient::default(); 81 | //! let data = Cursor::new("Hello World!"); 82 | //! 83 | //! match client.add(data).await { 84 | //! Ok(res) => println!("{}", res.hash), 85 | //! Err(e) => eprintln!("error adding file: {}", e) 86 | //! } 87 | //! } 88 | //! ``` 89 | //! 90 | //! #### With Actix 91 | //! 92 | //! ```no_run 93 | //! use ipfs_api::{IpfsApi, IpfsClient}; 94 | //! use std::io::Cursor; 95 | //! 96 | //! #[actix_rt::main] 97 | //! async fn main() { 98 | //! let client = IpfsClient::default(); 99 | //! let data = Cursor::new("Hello World!"); 100 | //! 101 | //! match client.add(data).await { 102 | //! Ok(res) => println!("{}", res.hash), 103 | //! Err(e) => eprintln!("error adding file: {}", e) 104 | //! } 105 | //! } 106 | //! ``` 107 | //! 108 | //! ### Reading a file from IPFS 109 | //! 110 | //! #### With Hyper 111 | //! 112 | //! ```no_run 113 | //! use futures::TryStreamExt; 114 | //! use ipfs_api::{IpfsApi, IpfsClient}; 115 | //! use std::io::{self, Write}; 116 | //! 117 | //! #[tokio::main] 118 | //! async fn main() { 119 | //! let client = IpfsClient::default(); 120 | //! 121 | //! match client 122 | //! .get("/test/file.json") 123 | //! .map_ok(|chunk| chunk.to_vec()) 124 | //! .try_concat() 125 | //! .await 126 | //! { 127 | //! Ok(res) => { 128 | //! let out = io::stdout(); 129 | //! let mut out = out.lock(); 130 | //! 131 | //! out.write_all(&res).unwrap(); 132 | //! } 133 | //! Err(e) => eprintln!("error getting file: {}", e) 134 | //! } 135 | //! } 136 | //! ``` 137 | //! 138 | //! #### With Actix 139 | //! 140 | //! ```no_run 141 | //! use futures::TryStreamExt; 142 | //! use ipfs_api::{IpfsApi, IpfsClient}; 143 | //! use std::io::{self, Write}; 144 | //! 145 | //! #[actix_rt::main] 146 | //! async fn main() { 147 | //! let client = IpfsClient::default(); 148 | //! 149 | //! match client 150 | //! .get("/test/file.json") 151 | //! .map_ok(|chunk| chunk.to_vec()) 152 | //! .try_concat() 153 | //! .await 154 | //! { 155 | //! Ok(res) => { 156 | //! let out = io::stdout(); 157 | //! let mut out = out.lock(); 158 | //! 159 | //! out.write_all(&res).unwrap(); 160 | //! } 161 | //! Err(e) => eprintln!("error getting file: {}", e) 162 | //! } 163 | //! } 164 | //! ``` 165 | //! 166 | //! ### Additional Examples 167 | //! 168 | //! There are also a bunch of examples included in the project, which 169 | //! I used for testing 170 | //! 171 | //! For a list of examples, run: 172 | //! 173 | //! ```sh 174 | //! $ cargo run --example 175 | //! ``` 176 | //! 177 | //! You can run any of the examples with cargo: 178 | //! 179 | //! ```sh 180 | //! $ cargo run --example add_file 181 | //! ``` 182 | //! 183 | 184 | #[cfg(feature = "with-hyper")] 185 | pub use ipfs_api_backend_hyper::*; 186 | 187 | #[cfg(feature = "with-actix")] 188 | pub use ipfs_api_backend_actix::*; 189 | 190 | #[cfg(not(any(feature = "with-actix", feature = "with-hyper")))] 191 | compile_error!("Pick exactly one of these features: with-hyper, with-actix"); 192 | -------------------------------------------------------------------------------- /ipfs-api/tests/test_backend.rs: -------------------------------------------------------------------------------- 1 | use ipfs_api::IpfsApi; 2 | 3 | // If this compiles, the test has passed, as unwrap() requires the Debug trait. 4 | #[allow(unused)] 5 | async fn test_use_client(client: &C) { 6 | // Validate that all variants of the Backend trait's Error type (Backend::Error) implement the Debug trait. 7 | client.version().await.unwrap(); 8 | } 9 | -------------------------------------------------------------------------------- /ipfs-api/tests/test_basic_auth.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | 8 | #[path = "test_support/lib.rs"] 9 | mod test_support; 10 | 11 | use test_support::client::{build_client, wait_for_server}; 12 | use test_support::container::{IpfsContainer, NginxContainer}; 13 | use test_support::images; 14 | 15 | use ipfs_api_versions::test_current_image; 16 | 17 | #[test_current_image] 18 | #[actix_rt::test] 19 | async fn test_basic_auth(image_name: &str, image_tag: &str) { 20 | let expected_version = images::extract_version(image_tag); 21 | 22 | let container = IpfsContainer::new("test_basic_auth_ipfs", image_name, image_tag) 23 | .await 24 | .unwrap(); 25 | 26 | { 27 | let api_url = format!("http://{}:5001", container.ip); 28 | let client = build_client(&api_url); 29 | let version = wait_for_server(&client).await.unwrap(); 30 | 31 | assert_eq!(expected_version, version.version); 32 | } 33 | 34 | let nginx = NginxContainer::new("test_basic_auth_nginx", &container.ip) 35 | .await 36 | .unwrap(); 37 | 38 | println!("Waiting for nginx"); 39 | 40 | nginx.wait_for().await.unwrap(); 41 | 42 | println!("Connecting to IPFS through nginx"); 43 | 44 | { 45 | let api_url = format!("http://{}", nginx.ip); 46 | let client = build_client(&api_url).with_credentials(&nginx.username, &nginx.password); 47 | let version = wait_for_server(&client).await.unwrap(); 48 | 49 | assert_eq!(expected_version, version.version); 50 | } 51 | 52 | println!("Tearing down nginx"); 53 | 54 | nginx.teardown().await.unwrap(); 55 | 56 | println!("Tearing down ipfs"); 57 | 58 | container.teardown().await.unwrap(); 59 | } 60 | -------------------------------------------------------------------------------- /ipfs-api/tests/test_get_version.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | 8 | #[path = "test_support/lib.rs"] 9 | mod test_support; 10 | 11 | use test_support::client::{build_client, wait_for_server}; 12 | use test_support::container::IpfsContainer; 13 | use test_support::images; 14 | 15 | use ipfs_api_versions::test_supported_images; 16 | 17 | #[test_supported_images] 18 | #[actix_rt::test] 19 | async fn test_get_version(image_name: &str, image_tag: &str) { 20 | let expected_version = images::extract_version(image_tag); 21 | 22 | let container_name = format!("test_get_version_{}", expected_version.replace('.', "-")); 23 | 24 | let container = IpfsContainer::new(&container_name, image_name, image_tag) 25 | .await 26 | .unwrap(); 27 | 28 | let api_url = format!("http://{}:5001", container.ip); 29 | let client = build_client(&api_url); 30 | let version = wait_for_server(&client).await.unwrap(); 31 | 32 | assert_eq!(expected_version, version.version); 33 | 34 | container.teardown().await.unwrap(); 35 | } 36 | -------------------------------------------------------------------------------- /ipfs-api/tests/test_support/client.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | 8 | use std::time::Duration; 9 | 10 | use ipfs_api::response::VersionResponse; 11 | use ipfs_api::{IpfsApi, IpfsClient, TryFromUri}; 12 | 13 | pub fn build_client(api_url: &str) -> IpfsClient { 14 | IpfsClient::from_str(api_url).unwrap() 15 | } 16 | 17 | pub async fn wait_for_server(client: &C) -> Result { 18 | cfg_if::cfg_if! { 19 | if #[cfg(feature = "with-actix")] { 20 | const MESSAGE: &str = "Failed to connect to host: Connection refused"; 21 | } else if #[cfg(feature = "with-hyper")] { 22 | const MESSAGE: &str = "tcp connect error"; 23 | } 24 | } 25 | 26 | let mut attempts = 0; 27 | 28 | loop { 29 | tokio::time::sleep(Duration::from_secs(5)).await; 30 | 31 | match client.version().await.map_err(|e| format!("{}", e)) { 32 | Ok(v) => { 33 | return Ok(v); 34 | } 35 | Err(msg) => { 36 | println!("Not ready yet: {}", msg); 37 | 38 | if msg.contains(MESSAGE) { 39 | attempts += 1; 40 | 41 | if attempts >= 4 { 42 | return Err(format!("Already tried {} times", attempts)); 43 | } 44 | } else { 45 | return Err(format!("Other failure: {}", msg)); 46 | } 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ipfs-api/tests/test_support/default-template.conf: -------------------------------------------------------------------------------- 1 | # Copyright 2022 rust-ipfs-api Developers 2 | # 3 | # Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | # copied, modified, or distributed except according to those terms. 7 | 8 | server { 9 | listen 80; 10 | 11 | location / { 12 | auth_basic "Restricted"; 13 | auth_basic_user_file /secrets/htpasswd; 14 | 15 | proxy_read_timeout 60; 16 | proxy_connect_timeout 60; 17 | 18 | proxy_pass http://replaced_at_runtime:5001; 19 | proxy_http_version 1.1; 20 | 21 | proxy_set_header Host $http_host; 22 | proxy_set_header X-Forwarded-Host $http_host; 23 | proxy_set_header X-Forwarded-Proto $scheme; 24 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ipfs-api/tests/test_support/errors.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | 8 | use passivized_docker_engine_client::errors::{DecCreateError, DecUseError}; 9 | 10 | #[derive(Debug, thiserror::Error)] 11 | pub enum TestError { 12 | #[error("Docker client creation error: {0}")] 13 | DockerClientCreate(#[from] DecCreateError), 14 | 15 | #[error("Docker client error: {0}")] 16 | DockerClientUse(DecUseError), 17 | 18 | #[error("I/O error: {0}")] 19 | Io(#[from] std::io::Error), 20 | } 21 | 22 | // Doesn't conform to the trait requirements of #[from] 23 | impl From for TestError { 24 | fn from(other: DecUseError) -> Self { 25 | Self::DockerClientUse(other) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ipfs-api/tests/test_support/images.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | 8 | pub mod nginx { 9 | pub const IMAGE: &str = "nginx"; 10 | pub const TAG: &str = "1.23-alpine"; 11 | } 12 | 13 | /// Extract version triple from an IPFS/Kubo Docker image tag. 14 | /// 15 | /// Result should match VersionResponse::version 16 | pub fn extract_version(image_tag: &str) -> String { 17 | image_tag.strip_prefix('v').unwrap().to_string() 18 | } 19 | -------------------------------------------------------------------------------- /ipfs-api/tests/test_support/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | 8 | // Each test compiles separately, but not all tests use everything in test support. 9 | #![allow(dead_code)] 10 | 11 | mod resources; 12 | 13 | pub mod client; 14 | pub mod container; 15 | pub mod errors; 16 | pub mod images; 17 | -------------------------------------------------------------------------------- /ipfs-api/tests/test_support/resources.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 rust-ipfs-api Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | 8 | use crate::test_support::errors::TestError; 9 | use std::path::{Path, PathBuf}; 10 | use std::str::FromStr; 11 | 12 | /// From a path foo/bar/qux.txt, remove foo/ 13 | fn strip_path_prefix(path: &Path) -> PathBuf { 14 | let base = path 15 | .components() 16 | .next() 17 | .unwrap() 18 | .as_os_str() 19 | .to_str() 20 | .unwrap(); 21 | 22 | path.strip_prefix(base).unwrap().to_owned() 23 | } 24 | 25 | async fn read_default_conf_template() -> Result { 26 | let raw_file = PathBuf::from_str(file!()).unwrap(); 27 | 28 | let file = if raw_file.exists() { 29 | raw_file 30 | } else { 31 | // Obviously this file exists, but the working dir might be confused by the tools running the test. 32 | strip_path_prefix(&raw_file) 33 | }; 34 | 35 | let absolute_file = file.canonicalize().unwrap(); 36 | 37 | let parent = absolute_file.parent().unwrap().to_owned(); 38 | 39 | let absolute = parent.canonicalize().unwrap().to_owned(); 40 | 41 | let path = absolute.join("default-template.conf"); 42 | 43 | Ok(tokio::fs::read_to_string(path).await?) 44 | } 45 | 46 | pub fn set_config_permissions(path: &Path) -> Result<(), std::io::Error> { 47 | use std::os::unix::fs::PermissionsExt; 48 | 49 | let f = std::fs::File::open(path)?; 50 | f.set_permissions(PermissionsExt::from_mode(0o644)) 51 | } 52 | 53 | pub async fn write_default_conf(ip: &str, output: &Path) -> Result<(), TestError> { 54 | let template = read_default_conf_template().await?; 55 | let config = template.replace("replaced_at_runtime", ip); 56 | 57 | println!("Writing {}", output.to_str().unwrap()); 58 | 59 | tokio::fs::write(output, config).await?; 60 | 61 | Ok(()) 62 | } 63 | -------------------------------------------------------------------------------- /rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "stable" 3 | components = ["rustfmt", "clippy"] 4 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | edition = "2021" 2 | reorder_imports = true 3 | --------------------------------------------------------------------------------