-
Notifications
You must be signed in to change notification settings - Fork 93
MultipartData is not composable due to lifetime restrictions #58
Comments
Do you mind showing me what you're trying to do? The borrowing has generally not been an issue before, and I'm hesitant to make such a sweeping change for one framework. There is |
I mentioned my use case in the original post:
This isn't about changing your library to work with one framework, this is about ensuring your library can meet any applicable use case. At present, you're imposing a rather strong restriction; your library is literally impossible to use under certain scenarios, and the restriction is unnecessary. As far as I can tell, your library is the most complete one of its kind, and the only one that doesn't parse eagerly. It would be a shame if there needed to exist yet another library to meet a use case this one can easily meet. |
Does the |
I don't want to save to the file system unnecessarily. I want the caller of the function to determine what to do with the file stream. For instance, it should be trivial to gzip the stream without copying the contents to the file system unnecessarily. I want a stream end-to-end. |
And allowing the user to consume the |
That's right. That's the "abstraction" part. |
Following up on this. Have you given this any more thought, @abonander? |
I have some ideas on how to make this work without breaking existing usage. I'll get back to you. |
I ended up making the |
Awesome! This looks like it'll do what I need. Am completely inundated with work for the next week or so but will play with this afterwards. |
Finally had a chance to give this a try. While the API seems like it will work (though I do find it a bit clumsy to work with, though maybe that's unavoidable), I've hit a bug. Here's what I'm doing, in pseudocode: let multipart = Multipart::with_body(body, boundary);
let mut field = multipart.into_entry();
let outcome = if let Some(file) = field.data.as_file() {
let mut temp_file = tempfile();
file.save_to_limited(&mut temp_file, 1 << 20).expect("ok.");
Success(temp_file)
} else {
Failure
};
// There should only be one field.
match field.next_entry() {
Ok(None) => { outcome }
Ok(Some(_)) => { Failure }
Err(e) => { Failure }
} The issue is that the program hangs on the call to Another bug is that calling |
@abonander Have you had a chance to mull over my last comment? This is a showstopper. |
I'm working on it. |
Awesome! Thanks. :) |
I've published In the process of fixing the hang I also added the entry API to |
Hello!
I'm considering using your library in Rocket, but the lifetime restrictions imposed by
MultipartData
make any kind of meaningful composition or abstraction impossible. For instance, it is not possible to call a function that creates aMultipart
structure, reads aMultipartData
entry from a stream, and returns aMultipartFile
. This same restriction means thatMultipartData
cannot be abstracted away in any meaningful manner.The issue is caused by the lifetime in
MultipartData
being derived from theread_entry
method inMultipart
, making it impossible for aMultipartData
object to outlive itsMultipart
parent object. There are two references inMultipartData
:str
in theText
variant.BoundaryReader<B>
inMultipartFile
in theFile
variant.The first can be easily removed by using a
String
instead of an&str
. The&str
seems wholly unnecessary, as doesline_buf
inMultipart
.The reference to the reader is more interesting. There are many ways to avoid this reference, but one particularly viable solution is to have an alternate API that moves the stream into the
MultipartField
. You can accomplish this by having aMultipartField::next()
method that consumes the current object and moves the internal stream to an optionally newly created one. Using this API to iterate through all fields would look something like:This is easy to use and is significantly more flexible. This allows for an
extract_reader
method to extract the underlying reader, which can be necessary.Please consider this API or other solutions that allow your library to be used in more contexts.
The text was updated successfully, but these errors were encountered: