1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
use crate::IpfsApi;
use reqwest;
use serde_json;
use failure::{Error, err_msg};
#[derive(Deserialize, Debug, PartialEq, Hash)]
#[serde(rename_all = "PascalCase")]
pub struct PinResponse {
pins: Vec<String>
}
#[derive(PartialEq)]
pub enum PinType {
Direct,
Indirect,
Recursive,
}
pub struct PinnedHash {
pub hash: String,
pub pin_type: PinType,
}
impl IpfsApi {
pub async fn pin_add(&self, hash: &str, recursive: bool) -> Result<PinResponse, Error> {
let mut url = self.get_url()?;
url.set_path("api/v0/pin/add");
url.query_pairs_mut()
.append_pair("arg", hash)
.append_pair("recursive", &recursive.to_string())
.append_pair("progress", "false");
Ok(reqwest::get(url).await?.json().await?)
}
pub async fn pin_rm(&self, hash: &str, recursive: bool) -> Result<PinResponse, Error> {
let mut url = self.get_url()?;
url.set_path("api/v0/pin/rm");
url.query_pairs_mut()
.append_pair("arg", hash)
.append_pair("recursive", &recursive.to_string());
Ok(reqwest::get(url).await?.json().await?)
}
pub async fn pin_list(&self) -> Result<Vec<PinnedHash>, Error> {
let mut url = self.get_url()?;
url.set_path("api/v0/pin/ls");
let resp: serde_json::Value = reqwest::get(url).await?.json().await?;
let mut hashes = Vec::new();
let keys = resp.get("Keys").ok_or(err_msg(""))?.as_object().ok_or(err_msg(""))?;
for (key, value) in keys.iter() {
hashes.push(PinnedHash {
hash: key.clone(),
pin_type: match &value.get("Type").ok_or(err_msg(""))?.as_str().ok_or(err_msg(""))? {
&"direct" => PinType::Direct,
&"indirect" => PinType::Indirect,
&"recursive" => PinType::Recursive,
_ => PinType::Direct
},
});
}
Ok(hashes)
}
}
#[cfg(test)]
mod tests {
use crate::IpfsApi;
use pin::PinType;
#[test]
fn test_pin_full() {
let api = IpfsApi::new("127.0.0.1", 5001);
let hello = "QmWATWQ7fVPP2EFGu71UkfnqhYXDYH566qy47CnJDgvs8u";
for pin in api.pin_list().unwrap() {
if pin.pin_type == PinType::Direct || pin.pin_type == PinType::Recursive {
api.pin_rm(&pin.hash, true).unwrap();
}
}
let resp = api.pin_add(hello, false).unwrap();
assert_eq!(resp.pins.len(), 1);
assert_eq!(resp.pins[0], "QmWATWQ7fVPP2EFGu71UkfnqhYXDYH566qy47CnJDgvs8u".to_string());
}
}