From 716a72fffdaaa780b6fa03f23f472d9a1d9a27f7 Mon Sep 17 00:00:00 2001 From: buckn Date: Mon, 14 Jul 2025 20:39:06 -0400 Subject: [PATCH] macro update --- src/lib.rs | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 31a13f5..2615a21 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,11 +2,14 @@ use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, ItemEnum, DeriveInput, Data}; + #[proc_macro_attribute] pub fn http_response(_attr: TokenStream, item: TokenStream) -> TokenStream { - let item_for_ast = item.clone(); // for parse_macro_input - let item_for_quote = item.clone(); // for syn::parse to quote + // Clone the input token stream for separate parsing uses + let item_for_ast = item.clone(); + let item_for_quote = item.clone(); + // Parse the input into a syntax tree let ast: DeriveInput = parse_macro_input!(item_for_ast as DeriveInput); let name = &ast.ident; @@ -15,9 +18,9 @@ pub fn http_response(_attr: TokenStream, item: TokenStream) -> TokenStream { quote! { impl Responsable for #name where - Self: serde::de::DeserializeOwned, + Self: serde::de::DeserializeOwned + Sized, { - fn receive(resp: actix_web::ClientResponse) -> Result { + fn receive(resp: actix_web::ClientResponse) -> Result> { let parsed = actix_web::rt::System::new() .block_on(async { resp.json::().await @@ -36,34 +39,36 @@ pub fn http_response(_attr: TokenStream, item: TokenStream) -> TokenStream { syn::Fields::Unnamed(fields) if fields.unnamed.len() == 1 => { let inner_ty = &fields.unnamed.first().unwrap().ty; Some(quote! { - if let Ok(inner) = <#inner_ty as Responsable>::receive(resp) { + if let Ok(inner) = <#inner_ty as Responsable>::receive(resp.clone()) { return Ok(#name::#vname(inner)); } }) } - _ => None + _ => None, } }); quote! { impl Responsable for #name { - fn receive(resp: actix_web::ClientResponse) -> Result { + fn receive(resp: actix_web::ClientResponse) -> Result> { #(#variant_arms)* - Err(std::io::Error::new( + Err(Box::new(std::io::Error::new( std::io::ErrorKind::Other, concat!("No matching enum variant in ", stringify!(#name)) - ).into()) + ))) } } } } - _ => panic!("#[HttpResponse] only supports structs and tuple-style enum variants"), + _ => panic!("#[http_response] only supports structs and tuple-style enum variants"), }; + // Parse the original item (struct or enum) for output let original: syn::Item = syn::parse(item_for_quote).expect("Failed to parse item as syn::Item"); + // Combine the original item and the impl block into final tokens let output = quote! { #original #impl_block @@ -71,7 +76,6 @@ pub fn http_response(_attr: TokenStream, item: TokenStream) -> TokenStream { output.into() } - #[proc_macro_derive(ResponseVec)] pub fn derive_response_vec(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput);