axum_extra::extract::multipart

Struct Multipart

Source
pub struct Multipart { /* private fields */ }
Available on crate feature multipart only.
Expand description

Extractor that parses multipart/form-data requests (commonly used with file uploads).

⚠️ Since extracting multipart form data from the request requires consuming the body, the Multipart extractor must be last if there are multiple extractors in a handler. See “the order of extractors”

§Example

use axum::{
    routing::post,
    Router,
};
use axum_extra::extract::Multipart;

async fn upload(mut multipart: Multipart) {
    while let Some(mut field) = multipart.next_field().await.unwrap() {
        let name = field.name().unwrap().to_string();
        let data = field.bytes().await.unwrap();

        println!("Length of `{}` is {} bytes", name, data.len());
    }
}

let app = Router::new().route("/upload", post(upload));

§Field Exclusivity

A Field represents a raw, self-decoding stream into multipart data. As such, only one Field from a given Multipart instance may be live at once. That is, a Field emitted by next_field() must be dropped before calling next_field() again. Failure to do so will result in an error.

use axum_extra::extract::Multipart;

async fn handler(mut multipart: Multipart) {
    let field_1 = multipart.next_field().await;

    // We cannot get the next field while `field_1` is still alive. Have to drop `field_1`
    // first.
    let field_2 = multipart.next_field().await;
    assert!(field_2.is_err());
}

In general you should consume Multipart by looping over the fields in order and make sure not to keep Fields around from previous loop iterations. That will minimize the risk of runtime errors.

§Differences between this and axum::extract::Multipart

axum::extract::Multipart uses lifetimes to enforce field exclusivity at compile time, however that leads to significant usability issues such as Field not being 'static.

axum_extra::extract::Multipart instead enforces field exclusivity at runtime which makes things easier to use at the cost of possible runtime errors.

Implementations§

Source§

impl Multipart

Source

pub async fn next_field(&mut self) -> Result<Option<Field>, MultipartError>

Yields the next Field if available.

Source

pub fn into_stream( self, ) -> impl Stream<Item = Result<Field, MultipartError>> + Send + 'static

Convert the Multipart into a stream of its fields.

Trait Implementations§

Source§

impl Debug for Multipart

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<S> FromRequest<S> for Multipart
where S: Send + Sync,

Source§

type Rejection = MultipartRejection

If the extractor fails it’ll use this “rejection” type. A rejection is a kind of error that can be converted into a response.
Source§

fn from_request<'life0, 'async_trait>( req: Request<Body>, _state: &'life0 S, ) -> Pin<Box<dyn Future<Output = Result<Self, Self::Rejection>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Perform the extraction.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more