Skip to content

Commit

Permalink
Fixup error output
Browse files Browse the repository at this point in the history
  • Loading branch information
Jake-Shadle committed Feb 19, 2024
1 parent 57f9f1b commit e76d847
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 64 deletions.
24 changes: 12 additions & 12 deletions schemars/tests/ui/invalid_validation_attrs.stderr
Original file line number Diff line number Diff line change
@@ -1,59 +1,59 @@
error: expected validate regex attribute to be a string: `regex = "..."`
--> $DIR/invalid_validation_attrs.rs:4:39
--> tests/ui/invalid_validation_attrs.rs:4:39
|
4 | pub struct Struct1(#[validate(regex = 0, foo, length(min = 1, equal = 2, bar))] String);
| ^

error: unknown schemars attribute `foo`
--> $DIR/invalid_validation_attrs.rs:7:42
--> tests/ui/invalid_validation_attrs.rs:7:42
|
7 | pub struct Struct2(#[schemars(regex = 0, foo, length(min = 1, equal = 2, bar))] String);
| ^^^

error: expected schemars regex attribute to be a string: `regex = "..."`
--> $DIR/invalid_validation_attrs.rs:7:39
--> tests/ui/invalid_validation_attrs.rs:7:39
|
7 | pub struct Struct2(#[schemars(regex = 0, foo, length(min = 1, equal = 2, bar))] String);
| ^

error: schemars attribute cannot contain both `equal` and `min`
--> $DIR/invalid_validation_attrs.rs:7:63
error: schemars attribute cannot contain both `min` and `equal`
--> tests/ui/invalid_validation_attrs.rs:7:63
|
7 | pub struct Struct2(#[schemars(regex = 0, foo, length(min = 1, equal = 2, bar))] String);
| ^^^^^

error: unknown item in schemars length attribute
--> $DIR/invalid_validation_attrs.rs:7:74
--> tests/ui/invalid_validation_attrs.rs:7:74
|
7 | pub struct Struct2(#[schemars(regex = 0, foo, length(min = 1, equal = 2, bar))] String);
| ^^^

error: schemars attribute cannot contain both `contains` and `regex`
--> $DIR/invalid_validation_attrs.rs:26:9
error: schemars attribute cannot contain both `regex` and `contains`
--> tests/ui/invalid_validation_attrs.rs:26:9
|
26 | contains = "bar",
| ^^^^^^^^

error: duplicate schemars attribute `regex`
--> $DIR/invalid_validation_attrs.rs:27:9
--> tests/ui/invalid_validation_attrs.rs:27:9
|
27 | regex(path = "baz"),
| ^^^^^

error: schemars attribute cannot contain both `phone` and `email`
--> $DIR/invalid_validation_attrs.rs:29:9
--> tests/ui/invalid_validation_attrs.rs:29:9
|
29 | email,
| ^^^^^

error: schemars attribute cannot contain both `phone` and `url`
--> $DIR/invalid_validation_attrs.rs:30:9
--> tests/ui/invalid_validation_attrs.rs:30:9
|
30 | url
| ^^^

error[E0425]: cannot find value `foo` in this scope
--> $DIR/invalid_validation_attrs.rs:12:17
--> tests/ui/invalid_validation_attrs.rs:12:17
|
12 | regex = "foo",
| ^^^^^ not found in this scope
2 changes: 1 addition & 1 deletion schemars/tests/validate_inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub struct Struct<'a> {
#[schemars(inner(length(min = 5, max = 100)))]
array_str_length: [&'a str; 2],
#[schemars(inner(contains(pattern = "substring...")))]
slice_str_contains: &'a[&'a str],
slice_str_contains: &'a [&'a str],
#[schemars(inner(regex = "STARTS_WITH_HELLO"))]
vec_str_regex: Vec<String>,
#[schemars(inner(length(min = 1, max = 100)))]
Expand Down
64 changes: 38 additions & 26 deletions schemars_derive/src/attr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,16 +127,13 @@ impl Attrs {
continue;
}

let mut boop = None;
let res = attr.parse_nested_meta(|meta| {
let path_str = ident_to_string!(meta);
let mut skip = false;

boop = Some(path_str.clone());

match path_str.as_str() {
WITH => {
if let Some(ls) = get_lit_str(cx, WITH, &meta)? {
if let Some(ls) = get_lit_str(cx, attr_type, WITH, &meta)? {
with.set_exclusive(
meta.path,
ls.parse()?,
Expand All @@ -146,7 +143,7 @@ impl Attrs {
}
}
SCHEMA_WITH => {
if let Some(ls) = get_lit_str(cx, SCHEMA_WITH, &meta)? {
if let Some(ls) = get_lit_str(cx, attr_type, SCHEMA_WITH, &meta)? {
schema_with.set_exclusive(
meta.path,
ls.parse()?,
Expand All @@ -156,17 +153,17 @@ impl Attrs {
}
}
TITLE => {
if let Some(ls) = get_lit_str(cx, TITLE, &meta)? {
if let Some(ls) = get_lit_str(cx, attr_type, TITLE, &meta)? {
title.set(meta.path, ls.value(), ignore_errors);
}
}
DESCRIPTION => {
if let Some(ls) = get_lit_str(cx, DESCRIPTION, &meta)? {
if let Some(ls) = get_lit_str(cx, attr_type, DESCRIPTION, &meta)? {
description.set(meta.path, ls.value(), ignore_errors);
}
}
"example" => {
if let Some(ls) = get_lit_str(cx, EXAMPLE, &meta)? {
if let Some(ls) = get_lit_str(cx, attr_type, EXAMPLE, &meta)? {
examples.push(ls.parse()?);
}
}
Expand All @@ -175,7 +172,7 @@ impl Attrs {
skip = true;
}
"crate" if is_schema_rs => {
if let Some(ls) = get_lit_str(cx, DESCRIPTION, &meta)? {
if let Some(ls) = get_lit_str(cx, attr_type, DESCRIPTION, &meta)? {
krate.set(meta.path, ls.parse()?, ignore_errors);
}
}
Expand Down Expand Up @@ -256,16 +253,20 @@ type Symbol = &'static str;
struct Attr<'c, T> {
cx: &'c Ctxt,
name: Symbol,
tokens: TokenStream,
value: Option<T>,
}

#[derive(Copy, Clone)]
struct Excl {
name: Symbol,
set: bool,
}

impl<'c, T> Attr<'c, T> {
fn none(cx: &'c Ctxt, name: Symbol) -> Self {
Self {
cx,
name,
tokens: TokenStream::new(),
value: None,
}
}
Expand All @@ -274,42 +275,40 @@ impl<'c, T> Attr<'c, T> {
&mut self,
obj: A,
value: T,
exl: impl IntoIterator<Item = (&'static str, bool)>,
exl: impl IntoIterator<Item = Excl>,
ie: bool,
) {
let tokens = obj.into_token_stream();

if self.value.is_some() {
if !ie {
self.cx.error_spanned_by(
tokens.clone(),
tokens,
format!("duplicate schemars attribute `{}`", self.name),
);
}

return;
}

let non_exclusive = exl.into_iter().fold(false, |acc, (name, set)| {
if set && !ie {
let non_exclusive = exl.into_iter().fold(false, |acc, excl| {
if excl.set && !ie {
self.cx.error_spanned_by(
tokens.clone(),
format!(
"schemars attribute cannot contain both `{}` and `{name}`",
self.name
"schemars attribute cannot contain both `{}` and `{}`",
excl.name, self.name
),
);
}

acc || set
acc || excl.set
});

if non_exclusive {
return;
}

// The old implemenation just overwrites
self.tokens = tokens;
self.value = Some(value);
}

Expand All @@ -321,8 +320,11 @@ impl<'c, T> Attr<'c, T> {
self.value
}

fn excl(&self) -> (&'static str, bool) {
(self.name, self.value.is_some())
fn excl(&self) -> Excl {
Excl {
name: self.name,
set: self.value.is_some(),
}
}
}

Expand All @@ -337,6 +339,15 @@ impl<'c> BoolAttr<'c> {
self.0.set(obj, (), ie);
}

fn set_true_exclusive<A: ToTokens>(
&mut self,
obj: A,
exl: impl IntoIterator<Item = Excl>,
ie: bool,
) {
self.0.set_exclusive(obj, (), exl, ie)
}

fn get(&self) -> bool {
self.0.value.is_some()
}
Expand All @@ -357,14 +368,16 @@ fn skip_item(input: syn::parse::ParseStream) -> syn::Result<()> {

fn get_lit_str(
cx: &Ctxt,
kind: &'static str,
attr_name: &'static str,
meta: &ParseNestedMeta,
) -> syn::Result<Option<syn::LitStr>> {
get_lit_str2(cx, attr_name, attr_name, meta)
get_lit_str2(cx, kind, attr_name, attr_name, meta)
}

fn get_lit_str2(
cx: &Ctxt,
kind: &'static str,
attr_name: &'static str,
meta_item_name: &'static str,
meta: &ParseNestedMeta,
Expand All @@ -383,16 +396,15 @@ fn get_lit_str2(
if !suffix.is_empty() {
cx.error_spanned_by(
lit,
format!("unexpected suffix `{}` on string literal", suffix),
format!("unexpected suffix `{suffix}` on string literal"),
);
}
Ok(Some(lit.clone()))
} else {
cx.error_spanned_by(
expr,
format!(
"expected serde {} attribute to be a string: `{} = \"...\"`",
attr_name, meta_item_name
"expected {kind} {attr_name} attribute to be a string: `{meta_item_name} = \"...\"`"
),
);
Ok(None)
Expand Down
Loading

0 comments on commit e76d847

Please sign in to comment.