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]
|
||||
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]
|
||||
rocket = { version = "0.5.0-dev", path = "../../core/lib" }
|
||||
|
|
|
@ -18,7 +18,7 @@ proc-macro = true
|
|||
indexmap = "1.0"
|
||||
quote = "1.0"
|
||||
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"
|
||||
glob = "0.3"
|
||||
|
||||
|
|
|
@ -328,7 +328,7 @@ fn incomplete_route(
|
|||
|
||||
let attribute = Attribute {
|
||||
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,
|
||||
data: method_attribute.data,
|
||||
|
|
|
@ -3,8 +3,8 @@ use devise::{*, ext::{TypeExt, SpanDiagnosticExt}};
|
|||
use syn::visit_mut::VisitMut;
|
||||
use syn::visit::Visit;
|
||||
|
||||
use crate::exports::*;
|
||||
use crate::proc_macro2::{Span, TokenStream, TokenTree};
|
||||
use crate::syn_ext::IdentExt;
|
||||
use crate::name::Name;
|
||||
|
||||
pub struct FormField {
|
||||
|
@ -15,7 +15,7 @@ pub struct FormField {
|
|||
#[derive(FromMeta)]
|
||||
pub struct FieldAttr {
|
||||
pub name: Option<FormField>,
|
||||
pub validate: Option<syn::Expr>,
|
||||
pub validate: Option<SpanWrapped<syn::Expr>>,
|
||||
}
|
||||
|
||||
impl FieldAttr {
|
||||
|
@ -89,6 +89,7 @@ impl FieldExt for Field<'_> {
|
|||
|
||||
fn name_view(&self) -> Result<syn::Expr> {
|
||||
let field_name = self.field_name()?;
|
||||
define_spanned_export!(self.span() => _form);
|
||||
let name_view = quote_spanned! { self.span() =>
|
||||
#_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)
|
||||
local: bool,
|
||||
) -> 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()
|
||||
.filter_map(|a| a.validate)
|
||||
.map(move |expr| {
|
||||
|
@ -219,9 +220,21 @@ pub fn validators<'v>(
|
|||
})
|
||||
.filter(move |(_, is_local)| *is_local == local)
|
||||
.map(move |(mut expr, _)| {
|
||||
let field = field.ident();
|
||||
let mut v = ValidationMutator { parent, local, field, visited: false };
|
||||
let field_span = field.ident().span()
|
||||
.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);
|
||||
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)]
|
||||
| ^^^^^^^^
|
||||
= 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)
|
||||
|
||||
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,
|
||||
}
|
||||
|
||||
#[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() { }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#[macro_use]extern crate rocket;
|
||||
|
||||
use rocket::http::Status;
|
||||
use rocket::http::{Status, ContentType};
|
||||
use rocket::form::{Form, Contextual, FromForm, FromFormField, Context};
|
||||
use rocket::data::TempFile;
|
||||
|
||||
|
@ -39,7 +39,7 @@ struct Submission<'v> {
|
|||
date: time::Date,
|
||||
#[field(validate = len(1..=250))]
|
||||
r#abstract: &'v str,
|
||||
#[field(validate = ext("pdf"))]
|
||||
#[field(validate = ext(ContentType::PDF))]
|
||||
file: TempFile<'v>,
|
||||
#[field(validate = len(1..))]
|
||||
category: Vec<Category>,
|
||||
|
@ -52,8 +52,7 @@ struct Account<'v> {
|
|||
#[field(validate = len(1..))]
|
||||
name: &'v str,
|
||||
password: Password<'v>,
|
||||
#[field(validate = contains('@'))]
|
||||
#[field(validate = omits(self.password.first))]
|
||||
#[field(validate = contains('@').or_else(msg!("invalid email address")))]
|
||||
email: &'v str,
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue