Feature Request: Allow add_with_options to support virtual/non-existent directory structures.
Closed this issue · 10 comments
This is something I can do using js-ipfs-http-client:
const dir_obj = [
{
path: "some.json",
content: JSON.stringify(object),
},
];
const add_options = {
wrapWithDirectory: true,
};
const add_result = await ipfs.add(obj, add_options);
I looked into writing the equivalent with build_base_request and request_stream_json like add_path does but couldn't because they are private.
Is there another way to do this already?
If not, I suppose I could take a swing at implementing it.
Would adding an Optional form argument be a good approach?
Something like:
async fn add_with_options<R>(
&self,
data: R,
add: request::Add<'_>,
mut form_option: Option<multipart::Form<'static>>,
) -> Result<response::AddResponse, Self::Error>
where
R: 'static + Read + Send + Sync,
{
if form_option.is_none() {
let mut form_unwrapped = multipart::Form::default();
form_unwrapped.add_reader("path", data);
form_option = Some(form_unwrapped);
}
self.request(add, form_option).await
}
Do you know of
yeah, I tried it using:
let json = serde_json::to_string(&p).unwrap();
let data = Cursor::new(json);
let add = ipfs_api::request::Add::builder()
.wrap_with_directory(true)
.build();
let result = match state.ipfs_client.add_with_options(data, add).await ...
but there seems to be two issues...
- when I use it, I get:
Parse(
Error("trailing characters", line: 2, column: 1),
)
- I couldn't find a way to define the directory structure, in this case, the "path" for data.
Am I missing something?
About thew error I'm not sure.
But if your using json data why not use IPLD via ipfs dag put?
I've just never tried it, my current usecase is based on uploading json. Not sure IPLD would fit the usecase, maybe it would. But regardless if it fits the usecase better or not, I would think we would want to support the functionality.
I understand.
ipfs add in this case is made for file not really json constructed programatically.
If your can fix it that would be good.
To be fair, this functionality is useful for other binary data as well, not necessarily just json.
We should be able to upload multiple files without manipulating the actual filesystem.
Using something like this:
let json = serde_json::to_string(&p).unwrap();
let data = Cursor::new(json);
let add = ipfs_api::request::Add::builder()
.wrap_with_directory(true)
.build();
let mut form = Form::default();
form.add_reader_file("path", data, "p.json");
let cid = match state
.ipfs_client
.add_with_options(data, add, Some(form))
.await ...
It should be possible using something like the code I posted originally, since that's basically how add_path already works. I'm new to rust though, so I've yet to make it work.
currently with.
#[inline]
async fn add_with_options<R>(
&self,
data: R,
add: request::Add<'_>,
form: Option<multipart::Form<'static>>,
) -> Result<response::AddResponse, Error>
where
R: 'static + Read + Send + Sync,
{
let mut form_option = form;
if form_option.is_none() {
let mut form_unwrapped = multipart::Form::default();
form_unwrapped.add_reader("path", data);
form_option = Some(form_unwrapped);
}
self.request(add, form_option).await
}
results in :
hidden type for `impl Trait` captures lifetime that does not appear in bounds rustc E0700
internal.rs(466, 10): hidden type `impl futures::Future` captures lifetime smaller than the function body
Looked it up, but not sure how to proceed.
Alright, I've got a working implementation here:
thoughts?
Maybe @ferristseng could chime in. API design is not really my forte.
IMO it looks good.
Thanks! I think this looks fine. I'll take a closer look this weekend, but could you make a PR for it?