Skip to content

Commit

Permalink
Add validations for conflicts of flatten with other meta items
Browse files Browse the repository at this point in the history
flatten doesn't work with many of the other field-level options, so emit errors when they are used together.
  • Loading branch information
TedDriggs committed Feb 22, 2024
1 parent 0a951cd commit 60bff90
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 0 deletions.
53 changes: 53 additions & 0 deletions core/src/options/input_field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ impl InputField {
skip: *self.skip.unwrap_or_default(),
post_transform: self.post_transform.as_ref(),
multiple: self.multiple.unwrap_or_default(),
flatten: self.flatten.is_present(),
}
}

Expand Down Expand Up @@ -132,6 +133,12 @@ impl ParseAttribute for InputField {
}

self.attr_name = FromMeta::from_meta(mi)?;

if self.flatten.is_present() {
return Err(
Error::custom("`flatten` and `rename` cannot be used together").with_span(mi),
);
}
} else if path.is_ident("default") {
if self.default.is_some() {
return Err(Error::duplicate_field_path(path).with_span(mi));
Expand All @@ -143,12 +150,24 @@ impl ParseAttribute for InputField {
}

self.with = Some(FromMeta::from_meta(mi)?);

if self.flatten.is_present() {
return Err(
Error::custom("`flatten` and `with` cannot be used together").with_span(mi),
);
}
} else if path.is_ident("skip") {
if self.skip.is_some() {
return Err(Error::duplicate_field_path(path).with_span(mi));
}

self.skip = FromMeta::from_meta(mi)?;

if self.skip.map(|v| *v).unwrap_or_default() && self.flatten.is_present() {
return Err(
Error::custom("`flatten` and `skip` cannot be used together").with_span(mi),
);
}
} else if path.is_ident("map") || path.is_ident("and_then") {
let transformer = path.get_ident().unwrap().clone();
if let Some(post_transform) = &self.post_transform {
Expand All @@ -173,12 +192,46 @@ impl ParseAttribute for InputField {
}

self.multiple = FromMeta::from_meta(mi)?;

if self.multiple == Some(true) && self.flatten.is_present() {
return Err(
Error::custom("`flatten` and `multiple` cannot be used together").with_span(mi),
);
}
} else if path.is_ident("flatten") {
if self.flatten.is_present() {
return Err(Error::duplicate_field_path(path).with_span(mi));
}

self.flatten = FromMeta::from_meta(mi)?;

let mut conflicts = Error::accumulator();

if self.multiple == Some(true) {
conflicts.push(
Error::custom("`flatten` and `multiple` cannot be used together").with_span(mi),
);
}

if self.attr_name.is_some() {
conflicts.push(
Error::custom("`flatten` and `rename` cannot be used together").with_span(mi),
);
}

if self.with.is_some() {
conflicts.push(
Error::custom("`flatten` and `with` cannot be used together").with_span(mi),
);
}

if self.skip.map(|v| *v).unwrap_or_default() {
conflicts.push(
Error::custom("`flatten` and `skip` cannot be used together").with_span(mi),
);
}

conflicts.finish()?;
} else {
return Err(Error::unknown_field_path(path).with_span(mi));
}
Expand Down
21 changes: 21 additions & 0 deletions tests/compile-fail/flatten_meta_conflicts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use darling::FromMeta;

#[derive(FromMeta)]
struct Inner {
left: String,
right: String,
}

#[derive(FromMeta)]
struct Outer {
#[darling(flatten, multiple, with = demo, skip = true)]
field: Inner,
}

#[derive(FromMeta)]
struct ThisIsFine {
#[darling(flatten, multiple = false)]
field: Inner,
}

fn main() {}
17 changes: 17 additions & 0 deletions tests/compile-fail/flatten_meta_conflicts.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error: `flatten` and `multiple` cannot be used together
--> tests/compile-fail/flatten_meta_conflicts.rs:11:24
|
11 | #[darling(flatten, multiple, with = demo, skip = true)]
| ^^^^^^^^

error: `flatten` and `with` cannot be used together
--> tests/compile-fail/flatten_meta_conflicts.rs:11:34
|
11 | #[darling(flatten, multiple, with = demo, skip = true)]
| ^^^^

error: `flatten` and `skip` cannot be used together
--> tests/compile-fail/flatten_meta_conflicts.rs:11:47
|
11 | #[darling(flatten, multiple, with = demo, skip = true)]
| ^^^^

0 comments on commit 60bff90

Please sign in to comment.