Implement the new and operator

This commit is contained in:
Aurelien Foucault 2020-10-03 21:34:29 +02:00
parent 216b363ce7
commit beb4b2238a
2 changed files with 47 additions and 35 deletions

View File

@ -129,34 +129,36 @@ pub fn generate_guards(
Some(ident) => { Some(ident) => {
match ident.to_string().as_str() { match ident.to_string().as_str() {
"guard" => { "guard" => {
println!("ident guard found {:#?}\n", ident); if args.nested.len() != 1 {
if args.nested.len() > 1 {
return Err(Error::new_spanned(args, "Chained rules isn't possible anymore, please use operators.").into()); return Err(Error::new_spanned(args, "Chained rules isn't possible anymore, please use operators.").into());
} }
// why moved ? Want to use it in error if let NestedMeta::Meta(rule) = &args.nested[0] {
match &args.nested[0] { return generate_guards(crate_name, rule);
NestedMeta::Meta(rule) => { } else {
println! ("rule sended = {:#?}\n", rule); return Err(Error::new_spanned(&args.nested[0], "Invalid rule.").into());
return generate_guards(crate_name, rule);
}
_ => {
return Err(Error::new_spanned(args, "Invalid guard (to be improve)").into());
}
} }
} }
"and" => { "and" => {
println!("ident and found {:#?}\n", ident); if args.nested.len() != 2 {
return Err(Error::new_spanned(args, "WIP").into()); return Err(Error::new_spanned(args, "and operator support only 2 operands.").into());
}
let first_rule: Option<TokenStream>;
let second_rule: Option<TokenStream>;
if let NestedMeta::Meta(rule) = &args.nested[0] {
first_rule = generate_guards(crate_name, rule)?;
} else {
return Err(Error::new_spanned(&args.nested[0], "Invalid rule.").into());
}
if let NestedMeta::Meta(rule) = &args.nested[1] {
second_rule = generate_guards(crate_name, rule)?;
} else {
return Err(Error::new_spanned(&args.nested[1], "Invalid rule.").into());
}
Ok(Some(quote! { #crate_name::guard::GuardExt::and(#first_rule, #second_rule) }))
} }
_ => { _ => {
let mut guards = None;
//args == "guard"
println!("items = {:#?}\n", &args.nested);
let ty = &args.path; let ty = &args.path;
//ty = the rule
println!("ty = {:#?}\n", ty);
let mut params = Vec::new(); let mut params = Vec::new();
//rules params
for attr in &args.nested { for attr in &args.nested {
if let NestedMeta::Meta(Meta::NameValue(nv)) = attr { if let NestedMeta::Meta(Meta::NameValue(nv)) = attr {
let name = &nv.path; let name = &nv.path;
@ -182,26 +184,16 @@ pub fn generate_guards(
); );
} }
} }
let guard = quote! { #ty { #(#params),* } }; Ok(Some(quote! { #ty { #(#params),* } }))
if guards.is_none() {
guards = Some(guard);
} else {
guards =
Some(quote! { #crate_name::guard::GuardExt::and(#guard, #guards) });
}
println!("end of function");
Ok(guards)
//return Err(Error::new_spanned(ident, "Invalid guard (to be improve 2)").into());
} }
} }
}, },
None => { None => {
println!("failed for the moment"); Err(Error::new_spanned(args, "Invalid guards").into())
return Err(Error::new_spanned(args, "WIP").into());
} }
} }
} }
_ => Err(Error::new_spanned(args, "Invalid guards (old)").into()), _ => Err(Error::new_spanned(args, "Invalid guards").into()),
} }
} }

View File

@ -42,19 +42,20 @@ impl Guard for UserGuard {
#[async_std::test] #[async_std::test]
pub async fn test_multiple_guards() { pub async fn test_multiple_guards() {
#[derive(SimpleObject)] #[derive(SimpleObject)]
struct Query { struct Query {
#[graphql(guard(RoleGuard(role = "Role::Admin")))] #[graphql(guard(and(RoleGuard(role = "Role::Admin"), UserGuard(username = r#""test""#))))]
value: i32, value: i32,
} }
#[derive(SimpleObject)] #[derive(SimpleObject)]
struct Mutation { struct Mutation {
value: i32, value_m: i32,
} }
let schema = Schema::new(Query { value: 10 }, Mutation {value: 11}, EmptySubscription); let schema = Schema::new(Query { value: 10 }, Mutation {valueM: 11}, EmptySubscription);
let query = "{ value }"; let query = "{ value }";
assert_eq!( assert_eq!(
@ -88,4 +89,23 @@ pub async fn test_multiple_guards() {
}] }]
); );
let query = "{ value }";
assert_eq!(
schema
.execute(
Request::new(query)
.data(Role::Admin)
.data(Username("test1".to_string()))
)
.await
.into_result()
.unwrap_err(),
vec![ServerError {
message: "Forbidden".to_string(),
locations: vec![Pos { line: 1, column: 3 }],
path: vec![PathSegment::Field("value".to_owned())],
extensions: None,
}]
);
} }