From 3a8092a5fa12de303837a20396a7a2c7c5729289 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 21 Jun 2026 13:09:32 +0900 Subject: [PATCH] docs(multipart): move derive examples to the core crate --- actix-multipart-derive/src/lib.rs | 102 ++---------------------------- actix-multipart/src/form/mod.rs | 101 +++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 97 deletions(-) diff --git a/actix-multipart-derive/src/lib.rs b/actix-multipart-derive/src/lib.rs index 0c9ab818d..06a5c92bd 100644 --- a/actix-multipart-derive/src/lib.rs +++ b/actix-multipart-derive/src/lib.rs @@ -1,6 +1,8 @@ //! Multipart form derive macro for Actix Web. //! -//! See [`macro@MultipartForm`] for usage examples. +//! See [`actix_multipart::form::MultipartForm`] for usage examples. +//! +//! [`actix_multipart::form::MultipartForm`]: https://docs.rs/actix-multipart/latest/actix_multipart/form/struct.MultipartForm.html #![doc(html_logo_url = "https://actix.rs/img/logo.png")] #![doc(html_favicon_url = "https://actix.rs/favicon.ico")] @@ -49,103 +51,9 @@ struct ParsedField<'t> { /// Implements `MultipartCollect` for a struct so that it can be used with the `MultipartForm` /// extractor. /// -/// # Basic Use +/// See [`actix_multipart::form::MultipartForm`] for supported fields and attributes. /// -/// Each field type should implement the `FieldReader` trait: -/// -/// ```ignore -/// use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm}; -/// -/// #[derive(MultipartForm)] -/// struct ImageUpload { -/// description: Text, -/// timestamp: Text, -/// image: TempFile, -/// } -/// ``` -/// -/// # Optional and List Fields -/// -/// You can also use `Vec` and `Option` provided that `T: FieldReader`. -/// -/// A [`Vec`] field corresponds to an upload with multiple parts under the [same field -/// name](https://www.rfc-editor.org/rfc/rfc7578#section-4.3). -/// -/// ```ignore -/// use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm}; -/// -/// #[derive(MultipartForm)] -/// struct Form { -/// category: Option>, -/// files: Vec, -/// } -/// ``` -/// -/// # Field Renaming -/// -/// You can use the `#[multipart(rename = "foo")]` attribute to receive a field by a different name. -/// -/// ```ignore -/// use actix_multipart::form::{tempfile::TempFile, MultipartForm}; -/// -/// #[derive(MultipartForm)] -/// struct Form { -/// #[multipart(rename = "files[]")] -/// files: Vec, -/// } -/// ``` -/// -/// # Field Limits -/// -/// You can use the `#[multipart(limit = "")]` attribute to set field level limits. The limit -/// string is parsed using [`bytesize`]. -/// -/// Note: the form is also subject to the global limits configured using `MultipartFormConfig`. -/// -/// ```ignore -/// use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm}; -/// -/// #[derive(MultipartForm)] -/// struct Form { -/// #[multipart(limit = "2 KiB")] -/// description: Text, -/// -/// #[multipart(limit = "512 MiB")] -/// files: Vec, -/// } -/// ``` -/// -/// # Unknown Fields -/// -/// By default fields with an unknown name are ignored. They can be rejected using the -/// `#[multipart(deny_unknown_fields)]` attribute: -/// -/// ```ignore -/// # use actix_multipart::form::MultipartForm; -/// #[derive(MultipartForm)] -/// #[multipart(deny_unknown_fields)] -/// struct Form { } -/// ``` -/// -/// # Duplicate Fields -/// -/// The behaviour for when multiple fields with the same name are received can be changed using the -/// `#[multipart(duplicate_field = "")]` attribute: -/// -/// - "ignore": (default) Extra fields are ignored. I.e., the first one is persisted. -/// - "deny": A `MultipartError::UnknownField` error response is returned. -/// - "replace": Each field is processed, but only the last one is persisted. -/// -/// Note that `Vec` fields will ignore this option. -/// -/// ```ignore -/// # use actix_multipart::form::MultipartForm; -/// #[derive(MultipartForm)] -/// #[multipart(duplicate_field = "deny")] -/// struct Form { } -/// ``` -/// -/// [`bytesize`]: https://docs.rs/bytesize/2 +/// [`actix_multipart::form::MultipartForm`]: https://docs.rs/actix-multipart/latest/actix_multipart/form/struct.MultipartForm.html #[proc_macro_derive(MultipartForm, attributes(multipart))] pub fn impl_multipart_form(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input: syn::DeriveInput = parse_macro_input!(input); diff --git a/actix-multipart/src/form/mod.rs b/actix-multipart/src/form/mod.rs index 51136869b..765b0a570 100644 --- a/actix-multipart/src/form/mod.rs +++ b/actix-multipart/src/form/mod.rs @@ -336,6 +336,107 @@ pub async fn discard_field(mut field: Field, limits: &mut Limits) -> Result<(), /// `multipart/related`, or non-multipart media types. /// /// Add a [`MultipartFormConfig`] to your app data to configure extraction. +/// +/// # Basic Use +/// +/// Each field type should implement the [`FieldReader`] trait: +/// +/// ```rust +/// use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm}; +/// +/// #[derive(MultipartForm)] +/// struct ImageUpload { +/// description: Text, +/// timestamp: Text, +/// image: TempFile, +/// } +/// ``` +/// +/// # Optional and List Fields +/// +/// You can also use [`Vec`](Vec) and [`Option`](Option) provided that `T: FieldReader`. +/// +/// A [`Vec`] field corresponds to an upload with multiple parts under the [same field +/// name](https://www.rfc-editor.org/rfc/rfc7578#section-4.3). +/// +/// ```rust +/// use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm}; +/// +/// #[derive(MultipartForm)] +/// struct Form { +/// category: Option>, +/// files: Vec, +/// } +/// ``` +/// +/// # Field Renaming +/// +/// You can use the `#[multipart(rename = "foo")]` attribute to receive a field by a different name. +/// +/// ```rust +/// use actix_multipart::form::{tempfile::TempFile, MultipartForm}; +/// +/// #[derive(MultipartForm)] +/// struct Form { +/// #[multipart(rename = "files[]")] +/// files: Vec, +/// } +/// ``` +/// +/// # Field Limits +/// +/// You can use the `#[multipart(limit = "")]` attribute to set field level limits. The limit +/// string is parsed using [`bytesize`]. +/// +/// Note: the form is also subject to the global limits configured using [`MultipartFormConfig`]. +/// +/// ```rust +/// use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm}; +/// +/// #[derive(MultipartForm)] +/// struct Form { +/// #[multipart(limit = "2 KiB")] +/// description: Text, +/// +/// #[multipart(limit = "512 MiB")] +/// files: Vec, +/// } +/// ``` +/// +/// # Unknown Fields +/// +/// By default fields with an unknown name are ignored. They can be rejected using the +/// `#[multipart(deny_unknown_fields)]` attribute: +/// +/// ```rust +/// use actix_multipart::form::MultipartForm; +/// +/// #[derive(MultipartForm)] +/// #[multipart(deny_unknown_fields)] +/// struct Form {} +/// ``` +/// +/// # Duplicate Fields +/// +/// The behaviour for when multiple fields with the same name are received can be changed using the +/// `#[multipart(duplicate_field = "")]` attribute: +/// +/// - "ignore": (default) Extra fields are ignored. I.e., the first one is persisted. +/// - "deny": A [`MultipartError::DuplicateField`] error response is returned. +/// - "replace": Each field is processed, but only the last one is persisted. +/// +/// Note that [`Vec`] fields will ignore this option. +/// +/// ```rust +/// use actix_multipart::form::MultipartForm; +/// +/// #[derive(MultipartForm)] +/// #[multipart(duplicate_field = "deny")] +/// struct Form {} +/// ``` +/// +/// [`bytesize`]: https://docs.rs/bytesize/2 +/// [`MultipartError::DuplicateField`]: crate::MultipartError::DuplicateField #[derive(Deref, DerefMut)] pub struct MultipartForm(pub T);