diff --git a/biscuit-auth/src/datalog/expression.rs b/biscuit-auth/src/datalog/expression.rs index d8d9b74b..314bcbcb 100644 --- a/biscuit-auth/src/datalog/expression.rs +++ b/biscuit-auth/src/datalog/expression.rs @@ -1141,6 +1141,15 @@ mod tests { Op::Value(Term::Integer(42)), Op::Unary(Unary::Ffi("test_un".to_owned())), Op::Binary(Binary::And), + Op::Value(Term::Integer(42)), + Op::Unary(Unary::Ffi("test_closure".to_owned())), + Op::Binary(Binary::And), + Op::Value(Term::Str(i)), + Op::Unary(Unary::Ffi("test_closure".to_owned())), + Op::Binary(Binary::And), + Op::Value(Term::Integer(42)), + Op::Unary(Unary::Ffi("test_fn".to_owned())), + Op::Binary(Binary::And), ]; let values = HashMap::new(); @@ -1172,7 +1181,29 @@ mod tests { } })), ); + let closed_over_int = 42; + let closed_over_string = "test".to_string(); + extern_funcs.insert( + "test_closure".to_owned(), + ExternFunc::new(Rc::new(move |left, right| match (&left, &right) { + (builder::Term::Integer(left), None) => { + Ok(builder::boolean(*left == closed_over_int)) + } + (builder::Term::Str(left), None) => { + Ok(builder::boolean(left == &closed_over_string)) + } + _ => { + println!("{left:?}, {right:?}"); + Err("expecting a single integer".to_string()) + } + })), + ); + extern_funcs.insert("test_fn".to_owned(), ExternFunc::new(Rc::new(toto))); let res = e.evaluate(&values, &mut tmp_symbols, &extern_funcs); assert_eq!(res, Ok(Term::Bool(true))); } + + fn toto(_left: builder::Term, _right: Option) -> Result { + Ok(builder::Term::Bool(true)) + } }