Skip to content

Commit

Permalink
Don't panic on unions in darling_core
Browse files Browse the repository at this point in the history
  • Loading branch information
TedDriggs committed Feb 16, 2021
1 parent 2922dd5 commit f6a4f6f
Show file tree
Hide file tree
Showing 8 changed files with 27 additions and 13 deletions.
14 changes: 14 additions & 0 deletions core/src/ast/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,20 @@ impl<V, F> Data<V, F> {
}
}

/// Creates an empty body of the same shape as the passed-in body.
///
/// `darling` does not support unions; calling this function with a union body will return an error.
pub fn try_empty_from(src: &syn::Data) -> Result<Self> {
match *src {
syn::Data::Enum(_) => Ok(Data::Enum(vec![])),
syn::Data::Struct(ref vd) => Ok(Data::Struct(Fields::empty_from(&vd.fields))),
// This deliberately doesn't set a span on the error message, as the error is most useful if
// applied to the call site of the offending macro. Given that the message is very generic,
// putting it on the union keyword ends up being confusing.
syn::Data::Union(_) => Err(Error::custom("Unions are not supported")),
}
}

/// Creates a new `Data<&'a V, &'a F>` instance from `Data<V, F>`.
pub fn as_ref<'a>(&'a self) -> Data<&'a V, &'a F> {
match *self {
Expand Down
8 changes: 4 additions & 4 deletions core/src/options/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ pub struct Core {

impl Core {
/// Partially initializes `Core` by reading the identity, generics, and body shape.
pub fn start(di: &syn::DeriveInput) -> Self {
Core {
pub fn start(di: &syn::DeriveInput) -> Result<Self> {
Ok(Core {
ident: di.ident.clone(),
generics: di.generics.clone(),
data: Data::empty_from(&di.data),
data: Data::try_empty_from(&di.data)?,
default: Default::default(),
// See https://github.com/TedDriggs/darling/issues/10: We default to snake_case
// for enums to help authors produce more idiomatic APIs.
Expand All @@ -57,7 +57,7 @@ impl Core {
map: Default::default(),
bound: Default::default(),
allow_unknown_fields: Default::default(),
}
})
}

fn as_codegen_default<'a>(&'a self) -> Option<codegen::DefaultExpression<'a>> {
Expand Down
2 changes: 1 addition & 1 deletion core/src/options/from_derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub struct FdiOptions {
impl FdiOptions {
pub fn new(di: &syn::DeriveInput) -> Result<Self> {
(FdiOptions {
base: OuterFrom::start(di),
base: OuterFrom::start(di)?,
vis: Default::default(),
generics: Default::default(),
data: Default::default(),
Expand Down
2 changes: 1 addition & 1 deletion core/src/options/from_field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub struct FromFieldOptions {
impl FromFieldOptions {
pub fn new(di: &syn::DeriveInput) -> Result<Self> {
(FromFieldOptions {
base: OuterFrom::start(di),
base: OuterFrom::start(di)?,
vis: Default::default(),
ty: Default::default(),
})
Expand Down
2 changes: 1 addition & 1 deletion core/src/options/from_meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub struct FromMetaOptions {
impl FromMetaOptions {
pub fn new(di: &syn::DeriveInput) -> Result<Self> {
(FromMetaOptions {
base: Core::start(di),
base: Core::start(di)?,
})
.parse_attributes(&di.attrs)?
.parse_body(&di.data)
Expand Down
2 changes: 1 addition & 1 deletion core/src/options/from_type_param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub struct FromTypeParamOptions {
impl FromTypeParamOptions {
pub fn new(di: &syn::DeriveInput) -> Result<Self> {
(FromTypeParamOptions {
base: OuterFrom::start(di),
base: OuterFrom::start(di)?,
bounds: None,
default: None,
})
Expand Down
2 changes: 1 addition & 1 deletion core/src/options/from_variant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub struct FromVariantOptions {
impl FromVariantOptions {
pub fn new(di: &DeriveInput) -> Result<Self> {
(FromVariantOptions {
base: OuterFrom::start(di),
base: OuterFrom::start(di)?,
discriminant: Default::default(),
fields: Default::default(),
supports: Default::default(),
Expand Down
8 changes: 4 additions & 4 deletions core/src/options/outer_from.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ pub struct OuterFrom {
}

impl OuterFrom {
pub fn start(di: &syn::DeriveInput) -> Self {
OuterFrom {
container: Core::start(di),
pub fn start(di: &syn::DeriveInput) -> Result<Self> {
Ok(OuterFrom {
container: Core::start(di)?,
attrs: Default::default(),
ident: Default::default(),
attr_names: Default::default(),
forward_attrs: Default::default(),
from_ident: Default::default(),
}
})
}
}

Expand Down

0 comments on commit f6a4f6f

Please sign in to comment.