Simplify macro implementation

This commit is contained in:
Jacob Halsey 2022-09-28 19:21:25 +01:00
parent 67e14cce75
commit b64460b123
1 changed files with 10 additions and 27 deletions

View File

@ -2,10 +2,10 @@ extern crate proc_macro;
use darling::{FromDeriveInput, FromField, FromMeta}; use darling::{FromDeriveInput, FromField, FromMeta};
use parse_size::parse_size; use parse_size::parse_size;
use proc_macro2::{Ident, TokenStream}; use proc_macro2::Ident;
use quote::quote; use quote::quote;
use std::collections::HashSet; use std::collections::HashSet;
use syn::{parse_macro_input, PathArguments, Type}; use syn::{parse_macro_input, Type};
#[derive(FromDeriveInput, Default)] #[derive(FromDeriveInput, Default)]
#[darling(attributes(multipart), default)] #[darling(attributes(multipart), default)]
@ -38,7 +38,7 @@ struct ParsedField<'t> {
serialization_name: String, serialization_name: String,
rust_name: &'t Ident, rust_name: &'t Ident,
limit: Option<usize>, limit: Option<usize>,
path: TokenStream, ty: &'t Type,
} }
#[proc_macro_derive(MultipartForm, attributes(multipart))] #[proc_macro_derive(MultipartForm, attributes(multipart))]
@ -74,27 +74,11 @@ pub fn impl_multipart_form(input: proc_macro::TokenStream) -> proc_macro::TokenS
as usize as usize
}); });
// Converts `TextField<String>` into `TextField::<String>` where appropriate
let ty = &field.ty;
let mut tp = match ty {
Type::Path(ref p) => p,
_ => panic!("Field must be a TypePath"),
}
.clone();
let last = tp.path.segments.last_mut().unwrap();
let type_args = last.arguments.clone();
last.arguments = PathArguments::None;
let path = if matches!(type_args, PathArguments::None) {
quote!(#tp)
} else {
quote!(#tp::#type_args)
};
Ok(ParsedField { Ok(ParsedField {
serialization_name, serialization_name,
rust_name, rust_name,
limit, limit,
path, ty: &field.ty,
}) })
}) })
.collect::<Result<Vec<_>, darling::Error>>() .collect::<Result<Vec<_>, darling::Error>>()
@ -131,9 +115,11 @@ pub fn impl_multipart_form(input: proc_macro::TokenStream) -> proc_macro::TokenS
let mut read_field_impl = quote!(); let mut read_field_impl = quote!();
for field in &parsed { for field in &parsed {
let name = &field.serialization_name; let name = &field.serialization_name;
let path = &field.path; let ty = &field.ty;
read_field_impl.extend(quote!( read_field_impl.extend(quote!(
#name => ::std::boxed::Box::pin(#path::handle_field(req, field, limits, state, #duplicate_action)), #name => ::std::boxed::Box::pin(
<#ty as ::actix_multipart::form::FieldGroupReader>::handle_field(req, field, limits, state, #duplicate_action)
),
)); ));
} }
@ -153,10 +139,9 @@ pub fn impl_multipart_form(input: proc_macro::TokenStream) -> proc_macro::TokenS
for field in &parsed { for field in &parsed {
let name = &field.serialization_name; let name = &field.serialization_name;
let rust_name = &field.rust_name; let rust_name = &field.rust_name;
let path = &field.path; let ty = &field.ty;
from_state_impl.extend(quote!( from_state_impl.extend(quote!(
#rust_name: #path::from_state(#name, &mut state)?, #rust_name: <#ty as ::actix_multipart::form::FieldGroupReader>::from_state(#name, &mut state)?,
)); ));
} }
@ -175,7 +160,6 @@ pub fn impl_multipart_form(input: proc_macro::TokenStream) -> proc_macro::TokenS
limits: &'t mut ::actix_multipart::form::Limits, limits: &'t mut ::actix_multipart::form::Limits,
state: &'t mut ::actix_multipart::form::State, state: &'t mut ::actix_multipart::form::State,
) -> ::std::pin::Pin<::std::boxed::Box<dyn ::std::future::Future<Output = ::std::result::Result<(), ::actix_multipart::MultipartError>> + 't>> { ) -> ::std::pin::Pin<::std::boxed::Box<dyn ::std::future::Future<Output = ::std::result::Result<(), ::actix_multipart::MultipartError>> + 't>> {
use ::actix_multipart::form::FieldGroupReader;
match field.name() { match field.name() {
#read_field_impl #read_field_impl
_ => return ::std::boxed::Box::pin(::std::future::ready(#unknown_field_result)), _ => return ::std::boxed::Box::pin(::std::future::ready(#unknown_field_result)),
@ -183,7 +167,6 @@ pub fn impl_multipart_form(input: proc_macro::TokenStream) -> proc_macro::TokenS
} }
fn from_state(mut state: ::actix_multipart::form::State) -> ::std::result::Result<Self, ::actix_multipart::MultipartError> { fn from_state(mut state: ::actix_multipart::form::State) -> ::std::result::Result<Self, ::actix_multipart::MultipartError> {
use ::actix_multipart::form::FieldGroupReader;
Ok(Self { Ok(Self {
#from_state_impl #from_state_impl
}) })