opendal_core/services/ipmfs/
core.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use std::fmt::Debug;
19use std::fmt::Write;
20use std::sync::Arc;
21
22use http::Request;
23use http::Response;
24
25use crate::raw::*;
26use crate::*;
27
28pub struct IpmfsCore {
29    pub info: Arc<AccessorInfo>,
30    pub root: String,
31    pub endpoint: String,
32}
33
34impl Debug for IpmfsCore {
35    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36        f.debug_struct("IpmfsCore")
37            .field("root", &self.root)
38            .field("endpoint", &self.endpoint)
39            .finish_non_exhaustive()
40    }
41}
42
43impl IpmfsCore {
44    pub async fn ipmfs_stat(&self, path: &str) -> Result<Response<Buffer>> {
45        let p = build_rooted_abs_path(&self.root, path);
46
47        let url = format!(
48            "{}/api/v0/files/stat?arg={}",
49            self.endpoint,
50            percent_encode_path(&p)
51        );
52
53        let req = Request::post(url);
54        let req = req.body(Buffer::new()).map_err(new_request_build_error)?;
55
56        self.info.http_client().send(req).await
57    }
58
59    pub async fn ipmfs_read(&self, path: &str, range: BytesRange) -> Result<Response<HttpBody>> {
60        let p = build_rooted_abs_path(&self.root, path);
61
62        let mut url = format!(
63            "{}/api/v0/files/read?arg={}",
64            self.endpoint,
65            percent_encode_path(&p)
66        );
67
68        write!(url, "&offset={}", range.offset()).expect("write into string must succeed");
69        if let Some(count) = range.size() {
70            write!(url, "&count={count}").expect("write into string must succeed")
71        }
72
73        let req = Request::post(url);
74        let req = req.body(Buffer::new()).map_err(new_request_build_error)?;
75
76        self.info.http_client().fetch(req).await
77    }
78
79    pub async fn ipmfs_rm(&self, path: &str) -> Result<Response<Buffer>> {
80        let p = build_rooted_abs_path(&self.root, path);
81
82        let url = format!(
83            "{}/api/v0/files/rm?arg={}",
84            self.endpoint,
85            percent_encode_path(&p)
86        );
87
88        let req = Request::post(url);
89        let req = req.body(Buffer::new()).map_err(new_request_build_error)?;
90
91        self.info.http_client().send(req).await
92    }
93
94    pub(crate) async fn ipmfs_ls(&self, path: &str) -> Result<Response<Buffer>> {
95        let p = build_rooted_abs_path(&self.root, path);
96
97        let url = format!(
98            "{}/api/v0/files/ls?arg={}&long=true",
99            self.endpoint,
100            percent_encode_path(&p)
101        );
102
103        let req = Request::post(url);
104        let req = req.body(Buffer::new()).map_err(new_request_build_error)?;
105
106        self.info.http_client().send(req).await
107    }
108
109    pub async fn ipmfs_mkdir(&self, path: &str) -> Result<Response<Buffer>> {
110        let p = build_rooted_abs_path(&self.root, path);
111
112        let url = format!(
113            "{}/api/v0/files/mkdir?arg={}&parents=true",
114            self.endpoint,
115            percent_encode_path(&p)
116        );
117
118        let req = Request::post(url);
119        let req = req.body(Buffer::new()).map_err(new_request_build_error)?;
120
121        self.info.http_client().send(req).await
122    }
123
124    /// Support write from reader.
125    pub async fn ipmfs_write(&self, path: &str, body: Buffer) -> Result<Response<Buffer>> {
126        let p = build_rooted_abs_path(&self.root, path);
127
128        let url = format!(
129            "{}/api/v0/files/write?arg={}&parents=true&create=true&truncate=true",
130            self.endpoint,
131            percent_encode_path(&p)
132        );
133
134        let multipart = Multipart::new().part(FormDataPart::new("data").content(body));
135
136        let req: http::request::Builder = Request::post(url);
137        let req = multipart.apply(req)?;
138
139        self.info.http_client().send(req).await
140    }
141}