use std::convert::Infallible;
use bytes::Bytes;
use futures_util::stream::Stream;
use multra::{Constraints, Multipart, SizeLimit};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let (stream, boundary) = get_byte_stream_from_somewhere().await;
let constraints = Constraints::new()
.allowed_fields(vec!["my_text_field", "my_file_field"])
.size_limit(
SizeLimit::new()
.whole_stream(15 * 1024 * 1024)
.per_field(10 * 1024 * 1024)
.for_field("my_text_field", 30 * 1024),
);
let mut multipart = Multipart::with_constraints(stream, boundary, constraints);
while let Some(field) = multipart.next_field().await? {
let name = field.name();
let file_name = field.file_name();
println!("Name: {:?}, File Name: {:?}", name, file_name);
let content = field.text().await?;
println!("Content: {:?}", content);
}
Ok(())
}
async fn get_byte_stream_from_somewhere()
-> (impl Stream<Item = Result<Bytes, Infallible>>, &'static str) {
let data = "--X-BOUNDARY\r\nContent-Disposition: form-data; name=\"my_text_field\"\r\n\r\nabcd\r\n--X-BOUNDARY\r\nContent-Disposition: form-data; name=\"my_file_field\"; filename=\"a-text-file.txt\"\r\nContent-Type: text/plain\r\n\r\nHello world\nHello\r\nWorld\rAgain\r\n--X-BOUNDARY--\r\n";
let stream = futures_util::stream::iter(
data.chars()
.map(|ch| ch.to_string())
.map(|part| Ok(Bytes::copy_from_slice(part.as_bytes()))),
);
(stream, "X-BOUNDARY")
}