Skip to content

Commit

Permalink
Error if enum variant don't have a field
Browse files Browse the repository at this point in the history
  • Loading branch information
kenoss committed Aug 25, 2024
1 parent 05e12aa commit 9ac4360
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 13 deletions.
47 changes: 34 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,24 +322,41 @@ fn gen_impl_fn_enum(
.map(|variant| {
let variant_ident = &variant.ident;
match &variant.fields {
syn::Fields::Named(_) => {
todo!();
syn::Fields::Named(fields) => {
if fields.named.len() != 1 {
return Err(syn::Error::new_spanned(
&variant.fields,
"fields of enum variant must be a field",
));
}

let ident = fields.named[0].ident.as_ref().unwrap();

Ok(quote! {
Self::#variant_ident { #ident } => #trait_path::#method_ident(#ident #(,#args)*)
})
}
syn::Fields::Unnamed(fields) => {
if fields.unnamed.len() != 1 {
todo!();
return Err(syn::Error::new_spanned(
&variant.fields,
"fields of enum variant must be a field",
));
}

quote! {
Ok(quote! {
Self::#variant_ident(x) => #trait_path::#method_ident(x #(,#args)*)
}
})
}
syn::Fields::Unit => {
todo!();
Err(syn::Error::new_spanned(
variant,
"fields of enum variant must be a field",
))
}
}
})
.collect_vec();
.collect::<syn::Result<Vec<_>>>()?;

let sig = generic_param_replacer.replace_signature(fn_ingredient.sig.clone());
Ok(quote! {
Expand Down Expand Up @@ -517,21 +534,25 @@ mod tests {
quote! { Hello },
quote! {
enum Hoge {
A(String),
B(char),
Named {
named: String,
},
Unnamed(char),
}
},
quote! {
enum Hoge {
A(String),
B(char),
Named {
named: String,
},
Unnamed(char),
}

impl Hello for Hoge {
fn hello(&self) -> String {
match self {
Self::A(x) => Hello::hello(x),
Self::B(x) => Hello::hello(x),
Self::Named { named } => Hello::hello(named),
Self::Unnamed(x) => Hello::hello(x),
}
}
}
Expand Down
28 changes: 28 additions & 0 deletions tests/ui/fail_fields_of_enum_must_be_a_field.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// TODO: Make `register()` is usable for trait definition.
mod private_for_thin_delegate {
#[thin_delegate::register(AsRef)]
pub trait AsRef<T: ?Sized> {
/// Converts this type into a shared reference of the (usually inferred) input type.
fn as_ref(&self) -> &T;
}
}

#[thin_delegate::derive_delegate(AsRef<str>)]
enum Named {
Named {
x: String,
y: String,
},
}

#[thin_delegate::derive_delegate(AsRef<str>)]
enum Unnamed {
Unnamed(String, String),
}

#[thin_delegate::derive_delegate(AsRef<str>)]
enum Unit {
Unit,
}

fn main() {}
21 changes: 21 additions & 0 deletions tests/ui/fail_fields_of_enum_must_be_a_field.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error: fields of enum variant must be a field
--> tests/ui/fail_fields_of_enum_must_be_a_field.rs:12:11
|
12 | Named {
| ___________^
13 | | x: String,
14 | | y: String,
15 | | },
| |_____^

error: fields of enum variant must be a field
--> tests/ui/fail_fields_of_enum_must_be_a_field.rs:20:12
|
20 | Unnamed(String, String),
| ^^^^^^^^^^^^^^^^

error: fields of enum variant must be a field
--> tests/ui/fail_fields_of_enum_must_be_a_field.rs:25:5
|
25 | Unit,
| ^^^^

0 comments on commit 9ac4360

Please sign in to comment.