Skip to content
This repository has been archived by the owner on Oct 23, 2022. It is now read-only.

[Pin Support][WIP] Adds required http endpoints for pinning support for rust ipfs #152

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion http/src/v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub mod bitswap;
pub mod block;
pub mod dag;
pub mod id;
pub mod pin;
pub mod pubsub;
pub mod refs;
pub mod swarm;
Expand Down Expand Up @@ -73,7 +74,7 @@ pub fn routes<T: IpfsTypes>(
warp::path!("key" / ..).and_then(not_implemented),
warp::path!("name" / ..).and_then(not_implemented),
warp::path!("object" / ..).and_then(not_implemented),
warp::path!("pin" / ..).and_then(not_implemented),
pin::add_pin(ipfs),
warp::path!("ping" / ..).and_then(not_implemented),
pubsub::routes(ipfs),
refs::local(ipfs),
Expand Down
71 changes: 71 additions & 0 deletions http/src/v0/pin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use crate::v0::support::with_ipfs;
use futures::future::join_all;
use ipfs::{Cid, Ipfs, IpfsTypes};
use serde::ser::SerializeStruct;
use serde::{Deserialize, Serialize, Serializer};
use std::str::FromStr;
use warp::{path, query, reply, Filter, Rejection, Reply};

#[derive(Debug, Deserialize)]
struct AddRequest {
args: Vec<String>,
recursive: bool,
progress: bool,
}

#[derive(Debug)]
struct AddResponse {
pins: Vec<String>,
progress: usize,
}

#[derive(Debug)]
struct InvalidCID;
impl warp::reject::Reject for InvalidCID {}

impl Serialize for AddResponse {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = serializer.serialize_struct("AddResponse", 2)?;
let serialized_pins: Vec<String> = self.pins.iter().map(|x| x.to_string()).collect();
state.serialize_field("pins", &serialized_pins)?;
state.serialize_field("progress", &self.progress)?;
state.end()
}
}

async fn pin_block_request<T: IpfsTypes>(
ipfs: Ipfs<T>,
request: AddRequest,
) -> Result<impl Reply, Rejection> {
let cids: Vec<Cid> = request
.args
.iter()
.map(|x| Cid::from_str(&x))
.collect::<Result<Vec<Cid>, _>>()
.map_err(|_err| warp::reject::custom(InvalidCID))?;
let dispatched_pins = cids.iter().map(|x| ipfs.pin_block(&x));
let completed = join_all(dispatched_pins).await;
let pins: Vec<String> = completed
.iter()
.zip(cids)
.filter(|x| x.0.is_ok())
.map(|x| x.1.to_string())
.collect();
let response: AddResponse = AddResponse {
pins,
progress: 100,
};
Ok(reply::json(&response))
}

pub fn add_pin<T: IpfsTypes>(
ipfs: &Ipfs<T>,
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
path!("pin" / "add")
.and(with_ipfs(ipfs))
.and(query::<AddRequest>())
.and_then(pin_block_request)
}