2021-11-15 03:08:56 +00:00
|
|
|
use darling::util::SpannedValue;
|
2021-11-14 13:09:14 +00:00
|
|
|
use darling::FromMeta;
|
|
|
|
use proc_macro2::TokenStream;
|
|
|
|
use quote::quote;
|
2021-11-15 03:08:56 +00:00
|
|
|
use syn::{Expr, Result};
|
2021-11-14 13:09:14 +00:00
|
|
|
|
|
|
|
#[derive(FromMeta, Default, Clone)]
|
|
|
|
pub struct Validators {
|
|
|
|
#[darling(default)]
|
|
|
|
multiple_of: Option<f64>,
|
|
|
|
#[darling(default)]
|
|
|
|
maximum: Option<f64>,
|
|
|
|
#[darling(default)]
|
|
|
|
minimum: Option<f64>,
|
|
|
|
#[darling(default)]
|
|
|
|
max_length: Option<usize>,
|
|
|
|
#[darling(default)]
|
|
|
|
min_length: Option<usize>,
|
|
|
|
#[darling(default)]
|
|
|
|
max_items: Option<usize>,
|
|
|
|
#[darling(default)]
|
|
|
|
min_items: Option<usize>,
|
|
|
|
#[darling(default, multiple)]
|
2021-11-15 03:08:56 +00:00
|
|
|
custom: Vec<SpannedValue<String>>,
|
2021-11-14 13:09:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Validators {
|
|
|
|
pub fn create_validators(
|
|
|
|
&self,
|
|
|
|
crate_name: &TokenStream,
|
|
|
|
value: TokenStream,
|
2021-11-15 03:08:56 +00:00
|
|
|
ty: TokenStream,
|
2021-11-15 01:12:13 +00:00
|
|
|
map_err: Option<TokenStream>,
|
2021-11-15 03:08:56 +00:00
|
|
|
) -> Result<TokenStream> {
|
2021-11-14 13:09:14 +00:00
|
|
|
let mut codes = Vec::new();
|
|
|
|
|
|
|
|
if let Some(n) = &self.multiple_of {
|
|
|
|
codes.push(quote! {
|
2021-11-15 01:12:13 +00:00
|
|
|
#crate_name::validators::multiple_of(#value, #n)
|
2021-11-14 13:09:14 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(n) = &self.maximum {
|
|
|
|
codes.push(quote! {
|
2021-11-15 01:12:13 +00:00
|
|
|
#crate_name::validators::maximum(#value, #n)
|
2021-11-14 13:09:14 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(n) = &self.minimum {
|
|
|
|
codes.push(quote! {
|
2021-11-15 01:12:13 +00:00
|
|
|
#crate_name::validators::minimum(#value, #n)
|
2021-11-14 13:09:14 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(n) = &self.max_length {
|
|
|
|
codes.push(quote! {
|
2021-11-15 01:12:13 +00:00
|
|
|
#crate_name::validators::max_length(#value, #n)
|
2021-11-14 13:09:14 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(n) = &self.min_length {
|
|
|
|
codes.push(quote! {
|
2021-11-15 01:12:13 +00:00
|
|
|
#crate_name::validators::min_length(#value, #n)
|
2021-11-14 13:09:14 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(n) = &self.max_items {
|
|
|
|
codes.push(quote! {
|
2021-11-15 01:12:13 +00:00
|
|
|
#crate_name::validators::max_items(#value, #n)
|
2021-11-14 13:09:14 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(n) = &self.min_items {
|
|
|
|
codes.push(quote! {
|
2021-11-15 01:12:13 +00:00
|
|
|
#crate_name::validators::min_items(#value, #n)
|
2021-11-14 13:09:14 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-11-15 03:08:56 +00:00
|
|
|
for s in &self.custom {
|
|
|
|
let expr: Expr = syn::parse_str(s)?;
|
|
|
|
codes.push(quote! {
|
|
|
|
#crate_name::CustomValidator::check(&(#expr), &ctx, #value).await
|
|
|
|
.map_err(|err_msg| #crate_name::InputValueError::<#ty>::custom(err_msg))
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-11-15 01:12:13 +00:00
|
|
|
let codes = codes.into_iter().map(|s| quote!(#s #map_err ?));
|
2021-11-15 03:08:56 +00:00
|
|
|
Ok(quote!(#(#codes;)*))
|
2021-11-14 13:09:14 +00:00
|
|
|
}
|
|
|
|
}
|