From 0f453a83eb35d11e0c511b5cb146d868034cd813 Mon Sep 17 00:00:00 2001 From: Yoshua Wuyts Date: Mon, 28 Sep 2020 00:16:40 +0200 Subject: [PATCH] more multipart --- Cargo.toml | 2 +- src/body.rs | 15 ++++++++++- src/lib.rs | 2 +- src/multipart/entry.rs | 58 +++++++++++++++++++++++++++++++++++++++--- src/multipart/mod.rs | 18 +++++++++---- 5 files changed, 83 insertions(+), 12 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4868342a..0adbdc06 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,7 @@ serde = { version = "1.0.106", features = ["derive"] } serde_urlencoded = "0.7.0" rand = "0.7.3" serde_qs = "0.7.0" -multipart = { version = "0.16.1", default-features = false, features = ["server"], optional = true } +multipart = { version = "0.16.1", default-features = false, features = ["server"] } [dev-dependencies] http = "0.2.0" diff --git a/src/body.rs b/src/body.rs index b5e9bdbb..b1755b76 100644 --- a/src/body.rs +++ b/src/body.rs @@ -3,7 +3,7 @@ use async_std::io::{self, Cursor}; use serde::{de::DeserializeOwned, Serialize}; use std::fmt::{self, Debug}; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::pin::Pin; use std::task::{Context, Poll}; @@ -423,6 +423,19 @@ impl Body { pub fn set_mime(&mut self, mime: impl Into) { self.mime = mime.into(); } + + /// Get the file name of the `Body`, if it's set. + pub fn file_name(&self) -> Option<&PathBuf> { + self.file_name.as_ref() + } + + /// Set the file name of the `Body`. + pub fn set_file_name

(&mut self, file_name: Option

) + where + P: AsRef, + { + self.file_name = file_name.map(|v| v.as_ref().to_owned()); + } } impl Debug for Body { diff --git a/src/lib.rs b/src/lib.rs index 6b38cd75..09c5641d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -136,10 +136,10 @@ mod status; mod status_code; mod version; +pub mod multipart; pub mod trace; cfg_unstable! { pub mod upgrade; - pub mod multipart; } pub use body::Body; diff --git a/src/multipart/entry.rs b/src/multipart/entry.rs index 54662021..42774655 100644 --- a/src/multipart/entry.rs +++ b/src/multipart/entry.rs @@ -1,7 +1,7 @@ -use crate::Body; +use crate::{bail, Body, Mime}; use std::fmt::{self, Debug}; -use std::path::PathBuf; +use std::path::Path; /// A single multipart entry. /// @@ -20,14 +20,64 @@ impl Entry { } } + /// Create an empty `Entry`. + pub fn empty(name: impl AsRef) -> Self { + Self { + name: name.as_ref().to_owned(), + body: Body::empty(), + } + } + + /// Create an `Entry` from a file. + /// + #[cfg(all(feature = "async_std", not(target_os = "unknown")))] + pub async fn from_file

(path: P) -> crate::Result + where + P: AsRef, + { + let path = path.as_ref(); + let name = match path.to_str() { + Some(p) => p.to_owned(), + None => bail!("Could not convert file name to unicode"), + }; + let body = Body::from_file(path).await?; + Ok(Self::new(name, body)) + } + /// Get the entry name. pub fn name(&self) -> &String { &self.name } + /// Set the entry name. + pub fn set_name(&mut self, name: S) + where + S: AsRef, + { + self.name = name.as_ref().to_owned(); + } + + /// Get the content type. + pub fn content_type(&self) -> Option { + todo!(); + } + + /// Set the content type. + pub fn set_content_type(&mut self, _mime: Option) { + todo!(); + } + /// Get the file name of the entry, if it's set. - pub fn file_name(&self) -> Option<&PathBuf> { - self.body.file_name.as_ref() + pub fn file_name(&self) -> Option<&Path> { + self.body.file_name().map(|p| p.as_path()) + } + + /// Set the file name of the `Body`. + pub fn set_file_name

(&mut self, file_name: Option

) + where + P: AsRef, + { + self.body.set_file_name(file_name); } } diff --git a/src/multipart/mod.rs b/src/multipart/mod.rs index 3ffb71c1..8e20242e 100644 --- a/src/multipart/mod.rs +++ b/src/multipart/mod.rs @@ -4,11 +4,16 @@ //! //! Request: //! ``` +//! use http_types::multipart::{Multipart, Entry}; +//! //! let mut req = Request::new(Method::Get, "http://example.website"); //! //! let mut multi = Multipart::new(); -//! multi.push("hello world"); -//! multi.push(Body::from_file("./cats.jpeg").await?); +//! multi.push(Entry::new("description", "hello world")); +//! +//! let mut entry = Entry::from_file("my_file", Body::from_file("./cats.jpeg").await?); +//! entry.set_file_name("cats.jpeg"); +//! multi.push("myFile", Body::from_file("./cats.jpeg").await?); //! //! req.set_body(multi); //! ``` @@ -16,6 +21,7 @@ //! Response: //! //! ``` +//! use http_types::multipart::{Multipart, Entry}; //! let mut res = Response::new(200); // get this from somewhere //! //! let mut entries = res.body_multipart(); @@ -55,9 +61,11 @@ impl Multipart { } /// Add a new entry to the `Multipart` instance. - pub fn push(&mut self, name: impl AsRef, body: impl Into) { - let entry = Entry::new(name, body); - self.entries.push(entry); + pub fn push(&mut self, entry: E) + where + E: Into, + { + self.entries.push(entry.into()); } }