Mock-up for a multipart client implementation

This commit is contained in:
Ruben De Smet 2020-11-13 14:52:53 +01:00
parent a929209967
commit e2a54e62d1
3 changed files with 56 additions and 0 deletions

View File

@ -18,13 +18,16 @@ path = "src/lib.rs"
[dependencies]
actix-web = { version = "3.0.0", default-features = false }
actix-service = "1.0.6"
actix-http = "2.1.0"
actix-utils = "2.0.0"
bytes = "0.5.3"
derive_more = "0.99.2"
httparse = "1.3"
futures = { version = "0.3.5", default-features = false }
futures-util = { version = "0.3.5", default-features = false }
log = "0.4"
mime = "0.3"
rand = "0.7"
twoway = "0.2"
[dev-dependencies]

View File

@ -0,0 +1,52 @@
//! Multipart payload support for Actix Web Client
use bytes::Bytes;
use futures::prelude::*;
pub struct Form<'a> {
boundary: String,
fields: Vec<Field<'a>>,
}
/// A field in a multipart Form
pub struct Field<'a> {
inner: FieldInner<'a>,
content_type: String,
content_length: Option<usize>,
}
impl<'a> Default for Form<'a> {
fn default() -> Self {
use rand::{distributions::Alphanumeric, thread_rng, Rng};
let rng = thread_rng();
Self::with_boundary(rng.sample_iter(&Alphanumeric).take(60).collect())
}
}
impl<'a> Form<'a> {
/// Constructs a new multipart Form with a specific boundary.
///
/// If you do not want to manually construct a boundary, use `Form::default()`.
pub fn with_boundary(boundary: String) -> Self {
Form {
boundary,
fields: Vec::new(),
}
}
pub fn add_stream<S>(&mut self, content_type: String, content: S)
where
S: Stream<Item = Result<Bytes, actix_http::Error>> + 'a,
{
self.fields.push(Field {
inner: FieldInner::Stream(Box::new(content)),
content_type,
content_length: None, // XXX
})
}
}
enum FieldInner<'a> {
Stream(Box<dyn Stream<Item = Result<Bytes, actix_http::Error>> + 'a>),
}

View File

@ -3,6 +3,7 @@
#![deny(rust_2018_idioms)]
#![allow(clippy::borrow_interior_mutable_const)]
pub mod client;
mod error;
mod extractor;
mod server;