Skip to content

Commit

Permalink
Convert usize into Exprs, add option to rename context
Browse files Browse the repository at this point in the history
  • Loading branch information
aumetra committed Aug 24, 2023
1 parent dfa1fed commit 0ab7029
Show file tree
Hide file tree
Showing 10 changed files with 34 additions and 64 deletions.
2 changes: 1 addition & 1 deletion garde/tests/rules/custom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ struct Context {
}

#[derive(Debug, garde::Validate)]
#[garde(context(Context))]
#[garde(context(Context as ctxxx))]
struct Test<'a> {
#[garde(custom(custom_validate_fn))]
a: &'a str,
Expand Down
7 changes: 0 additions & 7 deletions garde/tests/ui/compile-fail/byte_length_bad_min.rs

This file was deleted.

5 changes: 0 additions & 5 deletions garde/tests/ui/compile-fail/byte_length_bad_min.stderr

This file was deleted.

7 changes: 0 additions & 7 deletions garde/tests/ui/compile-fail/length_bad_min.rs

This file was deleted.

5 changes: 0 additions & 5 deletions garde/tests/ui/compile-fail/length_bad_min.stderr

This file was deleted.

37 changes: 9 additions & 28 deletions garde_derive/src/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use syn::parse_quote;
use syn::spanned::Spanned;

use crate::model;
use crate::util::MaybeFoldError;
use crate::util::{default_ctx_name, MaybeFoldError};

pub fn check(input: model::Input) -> syn::Result<model::Validate> {
let model::Input {
Expand All @@ -25,7 +25,7 @@ pub fn check(input: model::Input) -> syn::Result<model::Validate> {
Ok(v) => v,
Err(e) => {
error.maybe_fold(e);
parse_quote!(())
(parse_quote!(()), default_ctx_name())
}
};

Expand Down Expand Up @@ -92,15 +92,15 @@ fn check_attrs(attrs: &[(Span, model::Attr)]) -> syn::Result<()> {
}
}

fn get_context(attrs: &[(Span, model::Attr)]) -> syn::Result<syn::Type> {
fn get_context(attrs: &[(Span, model::Attr)]) -> syn::Result<(syn::Type, syn::Ident)> {
#![allow(clippy::single_match)]

let error = None;
let mut context = None;

for (_, attr) in attrs {
match attr {
model::Attr::Context(ty) => context = Some(ty),
model::Attr::Context(ty, ident) => context = Some((ty, ident)),
_ => {}
}
}
Expand All @@ -110,8 +110,8 @@ fn get_context(attrs: &[(Span, model::Attr)]) -> syn::Result<syn::Type> {
}

match context {
Some(v) => Ok((**v).clone()),
None => Ok(parse_quote!(())),
Some((ty, id)) => Ok(((**ty).clone(), (*id).clone())),
None => Ok((parse_quote!(()), default_ctx_name())),
}
}

Expand All @@ -122,7 +122,7 @@ fn get_options(attrs: &[(Span, model::Attr)]) -> model::Options {

for (_, attr) in attrs {
match attr {
model::Attr::Context(_) => {}
model::Attr::Context(..) => {}
model::Attr::AllowUnvalidated => options.allow_unvalidated = true,
}
}
Expand Down Expand Up @@ -309,7 +309,7 @@ fn check_rule(
PhoneNumber => apply!(rule_set, PhoneNumber(), span),
Length(v) => apply!(rule_set, Length(check_range(v)?), span),
ByteLength(v) => apply!(rule_set, ByteLength(check_range(v)?), span),
Range(v) => apply!(rule_set, Range(check_range_not_ord(v)?), span),
Range(v) => apply!(rule_set, Range(check_range(v)?), span),
Contains(v) => apply!(rule_set, Contains(v), span),
Prefix(v) => apply!(rule_set, Prefix(v), span),
Suffix(v) => apply!(rule_set, Suffix(v), span),
Expand Down Expand Up @@ -339,26 +339,7 @@ trait CheckRange: Sized {
fn check_range(self) -> syn::Result<model::ValidateRange<Self>>;
}

fn check_range<T>(range: model::Range<T>) -> syn::Result<model::ValidateRange<T>>
where
T: PartialOrd,
{
match (range.min, range.max) {
(Some(min), Some(max)) if min <= max => Ok(model::ValidateRange::Between(min, max)),
(Some(_), Some(_)) => Err(syn::Error::new(
range.span,
"`min` must be lower than or equal to `max`",
)),
(Some(min), None) => Ok(model::ValidateRange::GreaterThan(min)),
(None, Some(max)) => Ok(model::ValidateRange::LowerThan(max)),
(None, None) => Err(syn::Error::new(
range.span,
"range must have at least one of `min`, `max`",
)),
}
}

fn check_range_not_ord<T>(range: model::Range<T>) -> syn::Result<model::ValidateRange<T>> {
fn check_range<T>(range: model::Range<T>) -> syn::Result<model::ValidateRange<T>> {
match (range.min, range.max) {
(Some(min), Some(max)) => Ok(model::ValidateRange::Between(min, max)),
(Some(min), None) => Ok(model::ValidateRange::GreaterThan(min)),
Expand Down
6 changes: 4 additions & 2 deletions garde_derive/src/emit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub fn emit(input: model::Validate) -> TokenStream2 {
impl ToTokens for model::Validate {
fn to_tokens(&self, tokens: &mut TokenStream2) {
let ident = &self.ident;
let context_ty = &self.context;
let (context_ty, context_ident) = &self.context;
let (impl_generics, ty_generics, where_clause) = self.generics.split_for_impl();
let kind = &self.kind;

Expand All @@ -22,7 +22,9 @@ impl ToTokens for model::Validate {
type Context = #context_ty ;

#[allow(clippy::needless_borrow)]
fn validate(&self, __garde_user_ctx: &Self::Context) -> ::core::result::Result<(), ::garde::error::Errors> {
fn validate(&self, #context_ident: &Self::Context) -> ::core::result::Result<(), ::garde::error::Errors> {
let __garde_user_ctx = &#context_ident;

(
#kind
)
Expand Down
14 changes: 7 additions & 7 deletions garde_derive/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub struct Input {

#[repr(u8)]
pub enum Attr {
Context(Box<Type>),
Context(Box<Type>, Ident),
AllowUnvalidated,
}

Expand All @@ -27,7 +27,7 @@ impl Attr {

pub fn name(&self) -> &'static str {
match self {
Attr::Context(_) => "context",
Attr::Context(..) => "context",
Attr::AllowUnvalidated => "allow_unvalidated",
}
}
Expand Down Expand Up @@ -100,8 +100,8 @@ pub enum RawRuleKind {
IpV6,
CreditCard,
PhoneNumber,
Length(Range<usize>),
ByteLength(Range<usize>),
Length(Range<Expr>),
ByteLength(Range<Expr>),
Range(Range<Expr>),
Contains(Expr),
Prefix(Expr),
Expand Down Expand Up @@ -135,7 +135,7 @@ pub struct List<T> {
pub struct Validate {
pub ident: Ident,
pub generics: Generics,
pub context: Type,
pub context: (Type, Ident),
pub kind: ValidateKind,
pub options: Options,
}
Expand Down Expand Up @@ -211,8 +211,8 @@ pub enum ValidateRule {
IpV6,
CreditCard,
PhoneNumber,
Length(ValidateRange<usize>),
ByteLength(ValidateRange<usize>),
Length(ValidateRange<Expr>),
ByteLength(ValidateRange<Expr>),
Range(ValidateRange<Expr>),
Contains(Expr),
Prefix(Expr),
Expand Down
11 changes: 9 additions & 2 deletions garde_derive/src/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ use syn::ext::IdentExt;
use syn::parse::Parse;
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::token::As;
use syn::{DeriveInput, Token, Type};

use crate::model;
use crate::model::List;
use crate::util::MaybeFoldError;
use crate::util::{default_ctx_name, MaybeFoldError};

pub fn parse(input: DeriveInput) -> syn::Result<model::Input> {
let mut error = None;
Expand Down Expand Up @@ -90,7 +91,13 @@ impl Parse for model::Attr {
let content;
syn::parenthesized!(content in input);
let ty = content.parse::<Type>()?;
Ok(model::Attr::Context(Box::new(ty)))
let ident = if content.parse::<As>().is_ok() {
content.parse()?
} else {
default_ctx_name()
};

Ok(model::Attr::Context(Box::new(ty), ident))
}
"allow_unvalidated" => Ok(model::Attr::AllowUnvalidated),
_ => Err(syn::Error::new(ident.span(), "unrecognized attribute")),
Expand Down
4 changes: 4 additions & 0 deletions garde_derive/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@ impl MaybeFoldError for Option<syn::Error> {
}
}
}

pub fn default_ctx_name() -> syn::Ident {
syn::Ident::new("__garde_user_ctx", proc_macro2::Span::call_site())
}

0 comments on commit 0ab7029

Please sign in to comment.