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
+55 -1
View File
@@ -9,11 +9,17 @@ use crate::value::Value;
use std::collections::HashMap;
use anyhow::Result;
use anyhow::{Context, Result};
use data_encoding::BASE64;
pub fn register(m: &mut HashMap<&'static str, builtins::BuiltinFcn>) {
m.insert("base64.decode", (base64_decode, 1));
m.insert("json.is_valid", (json_is_valid, 1));
m.insert("json.marshal", (json_marshal, 1));
m.insert("jsonunmarshal", (json_unmarshal, 1));
m.insert("yaml.is_valid", (yaml_is_valid, 1));
m.insert("yaml.marshal", (yaml_marshal, 1));
m.insert("yaml.unmarshal", (yaml_unmarshal, 1));
}
fn base64_decode(span: &Span, params: &[Ref<Expr>], args: &[Value]) -> Result<Value> {
@@ -26,3 +32,51 @@ fn base64_decode(span: &Span, params: &[Ref<Expr>], args: &[Value]) -> Result<Va
String::from_utf8_lossy(&decoded_bytes).to_string(),
))
}
fn yaml_is_valid(span: &Span, params: &[Ref<Expr>], args: &[Value]) -> Result<Value> {
let name = "yaml.is_valid";
ensure_args_count(span, name, params, args, 1)?;
let yaml_str = ensure_string(name, &params[0], &args[0])?;
Ok(Value::Bool(Value::from_yaml_str(&yaml_str).is_ok()))
}
fn yaml_marshal(span: &Span, params: &[Ref<Expr>], args: &[Value]) -> Result<Value> {
let name = "yaml.marshal";
ensure_args_count(span, name, params, args, 1)?;
Ok(Value::String(
serde_yaml::to_string(&args[0])
.with_context(|| span.error("could not serialize to yaml"))?,
))
}
fn yaml_unmarshal(span: &Span, params: &[Ref<Expr>], args: &[Value]) -> Result<Value> {
let name = "yaml.unmarshal";
ensure_args_count(span, name, params, args, 1)?;
let yaml_str = ensure_string(name, &params[0], &args[0])?;
Value::from_yaml_str(&yaml_str).with_context(|| span.error("could not deserialize yaml."))
}
fn json_is_valid(span: &Span, params: &[Ref<Expr>], args: &[Value]) -> Result<Value> {
let name = "json.is_valid";
ensure_args_count(span, name, params, args, 1)?;
let json_str = ensure_string(name, &params[0], &args[0])?;
Ok(Value::Bool(Value::from_json_str(&json_str).is_ok()))
}
fn json_marshal(span: &Span, params: &[Ref<Expr>], args: &[Value]) -> Result<Value> {
let name = "json.marshal";
ensure_args_count(span, name, params, args, 1)?;
Ok(Value::String(
serde_json::to_string(&args[0])
.with_context(|| span.error("could not serialize to json"))?,
))
}
fn json_unmarshal(span: &Span, params: &[Ref<Expr>], args: &[Value]) -> Result<Value> {
let name = "json.unmarshal";
ensure_args_count(span, name, params, args, 1)?;
let json_str = ensure_string(name, &params[0], &args[0])?;
Value::from_json_str(&json_str).with_context(|| span.error("could not deserialize json."))
}