More library functions (#51)

- units.parse, units.parse_bytes
- json.is_valid, json.marshal, json.unmarshal
- yaml.is_valid, yaml.marshal, yaml.unmarshal
- object.subset
- set_diff

* Also print number of errors due to each missing function
* Also lock down fully passing OPA suites

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
This commit is contained in:
Anand Krishnamoorthi
2023-11-22 14:19:23 -08:00
committed by GitHub
parent e838d5af65
commit 4db2270dcf
14 changed files with 650 additions and 31 deletions
+29
View File
@@ -20,6 +20,7 @@ pub fn register(m: &mut HashMap<&'static str, builtins::BuiltinFcn>) {
m.insert("object.get", (get, 3));
m.insert("object.keys", (keys, 1));
m.insert("object.remove", (remove, 2));
m.insert("object.subset", (subset, 2));
}
fn json_filter_impl(v: &Value, filter: &Value) -> Value {
@@ -202,3 +203,31 @@ fn remove(span: &Span, params: &[Ref<Expr>], args: &[Value]) -> Result<Value> {
Ok(Value::Object(obj))
}
fn is_subset(sup: &Value, sub: &Value) -> bool {
match (sup, sub) {
(Value::Object(sup), Value::Object(sub)) => {
sub.iter().all(|(k, vsub)| {
match sup.get(k) {
// Some(vsup @ Value::Object(_)) => is_subset(vsup, vsub),
Some(vsup) => is_subset(vsup, vsub),
_ => false,
}
})
}
(Value::Set(sup), Value::Set(sub)) => sub.is_subset(sup),
(Value::Array(sup), Value::Array(sub)) => sup.windows(sub.len()).any(|w| w == &sub[..]),
(Value::Array(sup), Value::Set(_)) => {
let sup = Value::from_set(sup.iter().cloned().collect());
is_subset(&sup, sub)
}
(sup, sub) => sup == sub,
}
}
fn subset(span: &Span, params: &[Ref<Expr>], args: &[Value]) -> Result<Value> {
let name = "object.subset";
ensure_args_count(span, name, params, args, 2)?;
Ok(Value::Bool(is_subset(&args[0], &args[1])))
}