actix_form_data/
lib.rs

1/*
2 * This file is part of Actix Form Data.
3 *
4 * Copyright © 2026 asonix
5 *
6 * Actix Form Data is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Actix Form Data is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Actix Form Data.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20//! # Actix Form Data
21//! A library for retrieving form data from Actix Web's multipart streams. It can stream
22//! uploaded files onto the filesystem (its main purpose), but it can also parse associated
23//! form data.
24//!
25//! # Example
26//!
27//!```rust
28//! use actix_form_data::{Error, Field, Form, FormData, Multipart, Value};
29//! use actix_web::{
30//!     web::{post, resource},
31//!     App, HttpRequest, HttpResponse, HttpServer,
32//! };
33//! use futures_util::stream::StreamExt;
34//!
35//! struct UploadedContent(Value<()>);
36//!
37//! impl FormData for UploadedContent {
38//!     type Item = ();
39//!     type Error = Error;
40//!
41//!     fn form(_: &HttpRequest) -> Result<Form<Self::Item, Self::Error>, Self::Error> {
42//!         Ok(Form::new()
43//!             .field("Hey", Field::text())
44//!             .field(
45//!                 "Hi",
46//!                 Field::map()
47//!                     .field("One", Field::int())
48//!                     .field("Two", Field::float())
49//!                     .finalize(),
50//!             )
51//!             .field(
52//!                 "files",
53//!                 Field::array(Field::file(async move |_, _, mut stream| {
54//!                     while let Some(res) = stream.next().await {
55//!                         res?;
56//!                     }
57//!                     Ok(()) as Result<(), Error>
58//!                 })),
59//!             ))
60//!     }
61//!
62//!     fn extract(value: Value<Self::Item>) -> Result<Self, Self::Error>
63//!     where
64//!         Self: Sized,
65//!     {
66//!         Ok(UploadedContent(value))
67//!     }
68//! }
69//!
70//! async fn upload(Multipart(UploadedContent(value)): Multipart<UploadedContent>) -> HttpResponse {
71//!     println!("Uploaded Content: {:#?}", value);
72//!     HttpResponse::Created().finish()
73//! }
74//!
75//! #[actix_rt::main]
76//! async fn main() -> Result<(), anyhow::Error> {
77//!     HttpServer::new(move || App::new().service(resource("/upload").route(post().to(upload))))
78//!         .bind("127.0.0.1:8080")?
79//!         .run();
80//!         // .await?;
81//!
82//!     Ok(())
83//! }
84//!```
85
86mod error;
87mod extractor;
88mod types;
89mod upload;
90
91pub use self::{
92    error::{Error, ErrorKind},
93    extractor::{FormData, Multipart},
94    types::{Field, FileMeta, Form, Value},
95    upload::handle_multipart,
96};