mirror of https://github.com/rwf2/Rocket.git
Improve 'FromForm' derive error spans.
This commit is contained in:
parent
398a044eb0
commit
7628546ca2
|
@ -19,7 +19,7 @@ proc-macro = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
quote = "1.0"
|
quote = "1.0"
|
||||||
devise = { git = "https://github.com/SergioBenitez/Devise.git", rev = "bd221a4" }
|
devise = { git = "https://github.com/SergioBenitez/Devise.git", rev = "3ebe83" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rocket = { version = "0.5.0-dev", path = "../../core/lib" }
|
rocket = { version = "0.5.0-dev", path = "../../core/lib" }
|
||||||
|
|
|
@ -18,7 +18,7 @@ proc-macro = true
|
||||||
indexmap = "1.0"
|
indexmap = "1.0"
|
||||||
quote = "1.0"
|
quote = "1.0"
|
||||||
rocket_http = { version = "0.5.0-dev", path = "../http/" }
|
rocket_http = { version = "0.5.0-dev", path = "../http/" }
|
||||||
devise = { git = "https://github.com/SergioBenitez/Devise.git", rev = "bd221a4" }
|
devise = { git = "https://github.com/SergioBenitez/Devise.git", rev = "3ebe83" }
|
||||||
unicode-xid = "0.2"
|
unicode-xid = "0.2"
|
||||||
glob = "0.3"
|
glob = "0.3"
|
||||||
|
|
||||||
|
|
|
@ -328,7 +328,7 @@ fn incomplete_route(
|
||||||
|
|
||||||
let attribute = Attribute {
|
let attribute = Attribute {
|
||||||
method: SpanWrapped {
|
method: SpanWrapped {
|
||||||
full_span: method_span, span: method_span, value: Method(method)
|
full_span: method_span, key_span: None, span: method_span, value: Method(method)
|
||||||
},
|
},
|
||||||
uri: method_attribute.uri,
|
uri: method_attribute.uri,
|
||||||
data: method_attribute.data,
|
data: method_attribute.data,
|
||||||
|
|
|
@ -3,8 +3,8 @@ use devise::{*, ext::{TypeExt, SpanDiagnosticExt}};
|
||||||
use syn::visit_mut::VisitMut;
|
use syn::visit_mut::VisitMut;
|
||||||
use syn::visit::Visit;
|
use syn::visit::Visit;
|
||||||
|
|
||||||
use crate::exports::*;
|
|
||||||
use crate::proc_macro2::{Span, TokenStream, TokenTree};
|
use crate::proc_macro2::{Span, TokenStream, TokenTree};
|
||||||
|
use crate::syn_ext::IdentExt;
|
||||||
use crate::name::Name;
|
use crate::name::Name;
|
||||||
|
|
||||||
pub struct FormField {
|
pub struct FormField {
|
||||||
|
@ -15,7 +15,7 @@ pub struct FormField {
|
||||||
#[derive(FromMeta)]
|
#[derive(FromMeta)]
|
||||||
pub struct FieldAttr {
|
pub struct FieldAttr {
|
||||||
pub name: Option<FormField>,
|
pub name: Option<FormField>,
|
||||||
pub validate: Option<syn::Expr>,
|
pub validate: Option<SpanWrapped<syn::Expr>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FieldAttr {
|
impl FieldAttr {
|
||||||
|
@ -89,6 +89,7 @@ impl FieldExt for Field<'_> {
|
||||||
|
|
||||||
fn name_view(&self) -> Result<syn::Expr> {
|
fn name_view(&self) -> Result<syn::Expr> {
|
||||||
let field_name = self.field_name()?;
|
let field_name = self.field_name()?;
|
||||||
|
define_spanned_export!(self.span() => _form);
|
||||||
let name_view = quote_spanned! { self.span() =>
|
let name_view = quote_spanned! { self.span() =>
|
||||||
#_form::NameBuf::from((__c.__parent, #field_name))
|
#_form::NameBuf::from((__c.__parent, #field_name))
|
||||||
};
|
};
|
||||||
|
@ -201,7 +202,7 @@ pub fn validators<'v>(
|
||||||
parent: &'v syn::Ident, // field ident (if local) or form ident (if !local)
|
parent: &'v syn::Ident, // field ident (if local) or form ident (if !local)
|
||||||
local: bool,
|
local: bool,
|
||||||
) -> Result<impl Iterator<Item = syn::Expr> + 'v> {
|
) -> Result<impl Iterator<Item = syn::Expr> + 'v> {
|
||||||
Ok(FieldAttr::from_attrs(FieldAttr::NAME, &field.attrs)?
|
let exprs = FieldAttr::from_attrs(FieldAttr::NAME, &field.attrs)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|a| a.validate)
|
.filter_map(|a| a.validate)
|
||||||
.map(move |expr| {
|
.map(move |expr| {
|
||||||
|
@ -219,9 +220,21 @@ pub fn validators<'v>(
|
||||||
})
|
})
|
||||||
.filter(move |(_, is_local)| *is_local == local)
|
.filter(move |(_, is_local)| *is_local == local)
|
||||||
.map(move |(mut expr, _)| {
|
.map(move |(mut expr, _)| {
|
||||||
let field = field.ident();
|
let field_span = field.ident().span()
|
||||||
let mut v = ValidationMutator { parent, local, field, visited: false };
|
.join(field.ty.span())
|
||||||
|
.unwrap_or(field.ty.span());
|
||||||
|
|
||||||
|
let field_ident = field.ident().clone().with_span(field_span);
|
||||||
|
let mut v = ValidationMutator { parent, local, field: &field_ident, visited: false };
|
||||||
v.visit_expr_mut(&mut expr);
|
v.visit_expr_mut(&mut expr);
|
||||||
expr
|
|
||||||
}))
|
let span = expr.key_span.unwrap_or(field_span);
|
||||||
|
define_spanned_export!(span => _form);
|
||||||
|
syn::parse2(quote_spanned!(span => {
|
||||||
|
let __result: #_form::Result<'_, ()> = #expr;
|
||||||
|
__result
|
||||||
|
})).unwrap()
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(exprs)
|
||||||
}
|
}
|
||||||
|
|
|
@ -336,3 +336,44 @@ note: error occurred while deriving `FromForm`
|
||||||
136 | #[derive(FromForm)]
|
136 | #[derive(FromForm)]
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error[E0425]: cannot find function `unknown` in this scope
|
||||||
|
--> $DIR/from_form.rs:150:24
|
||||||
|
|
|
||||||
|
150 | #[field(validate = unknown())]
|
||||||
|
| ^^^^^^^ not found in this scope
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/from_form.rs:144:24
|
||||||
|
|
|
||||||
|
144 | #[field(validate = 123)]
|
||||||
|
| -------- ^^^ expected enum `Result`, found integer
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
|
||||||
|
= note: expected enum `Result<(), Errors<'_>>`
|
||||||
|
found type `{integer}`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/from_form.rs:157:5
|
||||||
|
|
|
||||||
|
157 | first: String,
|
||||||
|
| ^^^^^^^^^^^^^ expected enum `TempFile`, found struct `std::string::String`
|
||||||
|
|
|
||||||
|
= note: expected reference `&TempFile<'_>`
|
||||||
|
found reference `&std::string::String`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/from_form.rs:163:5
|
||||||
|
|
|
||||||
|
163 | first: String,
|
||||||
|
| ^^^^^^^^^^^^^ expected enum `TempFile`, found struct `std::string::String`
|
||||||
|
|
|
||||||
|
= note: expected reference `&TempFile<'_>`
|
||||||
|
found reference `&std::string::String`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/from_form.rs:162:28
|
||||||
|
|
|
||||||
|
162 | #[field(validate = ext("hello"))]
|
||||||
|
| ^^^^^^^ expected struct `ContentType`, found `&str`
|
||||||
|
|
|
@ -359,3 +359,44 @@ error: [note] error occurred while deriving `FromForm`
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error[E0425]: cannot find function `unknown` in this scope
|
||||||
|
--> $DIR/from_form.rs:150:24
|
||||||
|
|
|
||||||
|
150 | #[field(validate = unknown())]
|
||||||
|
| ^^^^^^^ not found in this scope
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/from_form.rs:144:24
|
||||||
|
|
|
||||||
|
144 | #[field(validate = 123)]
|
||||||
|
| -------- ^^^ expected enum `std::result::Result`, found integer
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
|
||||||
|
= note: expected enum `std::result::Result<(), Errors<'_>>`
|
||||||
|
found type `{integer}`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/from_form.rs:157:12
|
||||||
|
|
|
||||||
|
157 | first: String,
|
||||||
|
| ^^^^^^ expected enum `TempFile`, found struct `std::string::String`
|
||||||
|
|
|
||||||
|
= note: expected reference `&TempFile<'_>`
|
||||||
|
found reference `&std::string::String`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/from_form.rs:163:12
|
||||||
|
|
|
||||||
|
163 | first: String,
|
||||||
|
| ^^^^^^ expected enum `TempFile`, found struct `std::string::String`
|
||||||
|
|
|
||||||
|
= note: expected reference `&TempFile<'_>`
|
||||||
|
found reference `&std::string::String`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/from_form.rs:162:28
|
||||||
|
|
|
||||||
|
162 | #[field(validate = ext("hello"))]
|
||||||
|
| ^^^^^^^ expected struct `ContentType`, found `&str`
|
||||||
|
|
|
@ -139,4 +139,28 @@ struct BadName3 {
|
||||||
field: String,
|
field: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(FromForm)]
|
||||||
|
struct Validate0 {
|
||||||
|
#[field(validate = 123)]
|
||||||
|
first: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(FromForm)]
|
||||||
|
struct Validate1 {
|
||||||
|
#[field(validate = unknown())]
|
||||||
|
first: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(FromForm)]
|
||||||
|
struct Validate2 {
|
||||||
|
#[field(validate = ext(rocket::http::ContentType::HTML))]
|
||||||
|
first: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(FromForm)]
|
||||||
|
struct Validate3 {
|
||||||
|
#[field(validate = ext("hello"))]
|
||||||
|
first: String,
|
||||||
|
}
|
||||||
|
|
||||||
fn main() { }
|
fn main() { }
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#[macro_use]extern crate rocket;
|
#[macro_use]extern crate rocket;
|
||||||
|
|
||||||
use rocket::http::Status;
|
use rocket::http::{Status, ContentType};
|
||||||
use rocket::form::{Form, Contextual, FromForm, FromFormField, Context};
|
use rocket::form::{Form, Contextual, FromForm, FromFormField, Context};
|
||||||
use rocket::data::TempFile;
|
use rocket::data::TempFile;
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ struct Submission<'v> {
|
||||||
date: time::Date,
|
date: time::Date,
|
||||||
#[field(validate = len(1..=250))]
|
#[field(validate = len(1..=250))]
|
||||||
r#abstract: &'v str,
|
r#abstract: &'v str,
|
||||||
#[field(validate = ext("pdf"))]
|
#[field(validate = ext(ContentType::PDF))]
|
||||||
file: TempFile<'v>,
|
file: TempFile<'v>,
|
||||||
#[field(validate = len(1..))]
|
#[field(validate = len(1..))]
|
||||||
category: Vec<Category>,
|
category: Vec<Category>,
|
||||||
|
@ -52,8 +52,7 @@ struct Account<'v> {
|
||||||
#[field(validate = len(1..))]
|
#[field(validate = len(1..))]
|
||||||
name: &'v str,
|
name: &'v str,
|
||||||
password: Password<'v>,
|
password: Password<'v>,
|
||||||
#[field(validate = contains('@'))]
|
#[field(validate = contains('@').or_else(msg!("invalid email address")))]
|
||||||
#[field(validate = omits(self.password.first))]
|
|
||||||
email: &'v str,
|
email: &'v str,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue