Skip to content

Commit

Permalink
feat: better errors in derive(ValueDeserialize) (#1095)
Browse files Browse the repository at this point in the history
  • Loading branch information
obmarg authored Nov 12, 2024
1 parent 1695b40 commit 735321a
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 25 deletions.
18 changes: 8 additions & 10 deletions cynic-parser-deser-macros/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub struct StructAttribute {
}

impl StructAttribute {
pub fn from_attrs(attrs: &[Attribute]) -> Self {
pub fn from_attrs(attrs: &[Attribute]) -> Result<Self, syn::Error> {
attrs
.iter()
.filter(|attr| attr.path().is_ident("deser"))
Expand All @@ -34,11 +34,10 @@ impl StructAttribute {
} else {
Err(meta.error("unsupported attribute"))
}
})
.unwrap();
output
})?;
Ok::<_, syn::Error>(output)
})
.fold(Self::default(), |acc, inc| acc.merge(inc))
.try_fold(Self::default(), |acc, inc| Ok(acc.merge(inc?)))
}

fn merge(mut self, other: Self) -> Self {
Expand Down Expand Up @@ -69,7 +68,7 @@ pub enum FieldDefault {
}

impl FieldAttributes {
pub fn from_field(field: &Field, defaults: FieldAttributes) -> Self {
pub fn from_field(field: &Field, defaults: FieldAttributes) -> Result<Self, syn::Error> {
field
.attrs
.iter()
Expand Down Expand Up @@ -101,11 +100,10 @@ impl FieldAttributes {
} else {
Err(meta.error("unsupported attribute"))
}
})
.unwrap();
output
})?;
Ok::<_, syn::Error>(output)
})
.fold(defaults, |acc, inc| acc.merge(inc))
.try_fold(defaults, |acc, inc| Ok(acc.merge(inc?)))
}

fn merge(mut self, other: Self) -> Self {
Expand Down
37 changes: 22 additions & 15 deletions cynic-parser-deser-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ mod attributes;
mod renames;

use attributes::{FieldAttributes, FieldDefault, StructAttribute};
use proc_macro2::TokenStream;
use proc_macro2::{Span, TokenStream};
use quote::{format_ident, quote, ToTokens};
use syn::{parse_quote, Fields};

Expand All @@ -12,21 +12,25 @@ pub fn value_deserialize(input: proc_macro::TokenStream) -> proc_macro::TokenStr

let ast = syn::parse_macro_input!(input as syn::DeriveInput);

match value_deser_impl(ast) {
match value_deser_impl(&ast) {
Ok(tokens) => tokens.into(),
Err(_) => {
todo!("put out a dummy impl as well as the compile errors");
// e.to_compile_error().into(),
Err(error) => {
// TODO: Output a dummy impl...
let compile_error = error.to_compile_error();
quote! {
#compile_error
}
.into()
}
}
}

fn value_deser_impl(ast: syn::DeriveInput) -> Result<TokenStream, ()> {
let syn::Data::Struct(data) = ast.data else {
fn value_deser_impl(ast: &syn::DeriveInput) -> Result<TokenStream, syn::Error> {
let syn::Data::Struct(data) = &ast.data else {
panic!("ValueDeserialize can only be derived on structs");
};

let ident = ast.ident;
let ident = &ast.ident;

let (original_impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
let (impl_generics, deser_lifetime) = match ast.generics.lifetimes().next() {
Expand All @@ -45,23 +49,26 @@ fn value_deser_impl(ast: syn::DeriveInput) -> Result<TokenStream, ()> {
}
};

let Fields::Named(named) = data.fields else {
panic!("ValueDeserialize can only be derived on structs with named fields");
let Fields::Named(named) = &data.fields else {
return Err(syn::Error::new(
Span::call_site(),
"ValueDeserialize can only be derived on structs with named fields",
));
};

let struct_attrs = StructAttribute::from_attrs(&ast.attrs);
let struct_attrs = StructAttribute::from_attrs(&ast.attrs)?;
let default_field_attrs = struct_attrs.to_field_defaults();

let fields = named
.named
.iter()
.map(|field| {
(
Ok::<_, syn::Error>((
field,
FieldAttributes::from_field(field, default_field_attrs.clone()),
)
FieldAttributes::from_field(field, default_field_attrs.clone())?,
))
})
.collect::<Vec<_>>();
.collect::<Result<Vec<_>, _>>()?;

let field_names = named
.named
Expand Down

0 comments on commit 735321a

Please sign in to comment.