From d417910a164f8d9515056be122177f5983d49d50 Mon Sep 17 00:00:00 2001 From: Tristan Bouchard Date: Mon, 4 Apr 2022 00:26:11 -0700 Subject: [PATCH] Add `Field::chunk` (#901) * Added chunk function to multipart field This fixes not being able to stream data from a multipart directly into a file or other output. * doc comment for clarification of usage and &mut self * fixed formatting * Corrected example to reflex best practices * Removed unwrap * clean up docs * update changelog Co-authored-by: David Pedersen --- axum/CHANGELOG.md | 5 +++- axum/src/extract/multipart.rs | 45 +++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/axum/CHANGELOG.md b/axum/CHANGELOG.md index 5e72b2c5..abdb6093 100644 --- a/axum/CHANGELOG.md +++ b/axum/CHANGELOG.md @@ -7,7 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 # Unreleased -- None. +- **added:** Add `axum::extract::multipart::Field::chunk` method for streaming a single chunk from + the field ([#901]) + +[#901]: https://github.com/tokio-rs/axum/pull/901 # 0.5.1 (03. April, 2022) diff --git a/axum/src/extract/multipart.rs b/axum/src/extract/multipart.rs index bfe4b7a1..8f58455f 100644 --- a/axum/src/extract/multipart.rs +++ b/axum/src/extract/multipart.rs @@ -142,6 +142,51 @@ impl<'a> Field<'a> { pub async fn text(self) -> Result { self.inner.text().await.map_err(MultipartError::from_multer) } + + /// Stream a chunk of the field data. + /// + /// When the field data has been exhausted, this will return [`None`]. + /// + /// Note this does the same thing as `Field`'s [`Stream`] implementation. + /// + /// # Example + /// + /// ``` + /// use axum::{ + /// extract::Multipart, + /// routing::post, + /// response::IntoResponse, + /// http::StatusCode, + /// Router, + /// }; + /// + /// async fn upload(mut multipart: Multipart) -> Result<(), (StatusCode, String)> { + /// while let Some(mut field) = multipart + /// .next_field() + /// .await + /// .map_err(|err| (StatusCode::BAD_REQUEST, err.to_string()))? + /// { + /// while let Some(chunk) = field + /// .chunk() + /// .await + /// .map_err(|err| (StatusCode::BAD_REQUEST, err.to_string()))? + /// { + /// println!("received {} bytes", chunk.len()); + /// } + /// } + /// + /// Ok(()) + /// } + /// + /// let app = Router::new().route("/upload", post(upload)); + /// # let _: Router = app; + /// ``` + pub async fn chunk(&mut self) -> Result, MultipartError> { + self.inner + .chunk() + .await + .map_err(MultipartError::from_multer) + } } /// Errors associated with parsing `multipart/form-data` requests.