use cedar_policy::{eval_expression, Entities, EvalResult, Expression};
use clap::Args;
use miette::WrapErr;
use std::str::FromStr;
use crate::{load_entities, CedarExitCode, OptionalSchemaArgs, RequestArgs};
#[derive(Args, Debug)]
pub struct EvaluateArgs {
#[command(flatten)]
pub request: RequestArgs,
#[command(flatten)]
pub schema: OptionalSchemaArgs,
#[arg(long = "entities", value_name = "FILE")]
pub entities_file: Option<String>,
#[arg(value_name = "EXPRESSION")]
pub expression: String,
}
pub fn evaluate(args: &EvaluateArgs) -> (CedarExitCode, EvalResult) {
println!();
let schema = match args.schema.get_schema() {
Ok(opt) => opt,
Err(e) => {
println!("{e:?}");
return (CedarExitCode::Failure, EvalResult::Bool(false));
}
};
let request = match args.request.get_request(schema.as_ref()) {
Ok(q) => q,
Err(e) => {
println!("{e:?}");
return (CedarExitCode::Failure, EvalResult::Bool(false));
}
};
let expr =
match Expression::from_str(&args.expression).wrap_err("failed to parse the expression") {
Ok(expr) => expr,
Err(e) => {
println!("{:?}", e.with_source_code(args.expression.clone()));
return (CedarExitCode::Failure, EvalResult::Bool(false));
}
};
let entities = match &args.entities_file {
None => Entities::empty(),
Some(file) => match load_entities(file, schema.as_ref()) {
Ok(entities) => entities,
Err(e) => {
println!("{e:?}");
return (CedarExitCode::Failure, EvalResult::Bool(false));
}
},
};
match eval_expression(&request, &entities, &expr).wrap_err("failed to evaluate the expression")
{
Err(e) => {
println!("{e:?}");
(CedarExitCode::Failure, EvalResult::Bool(false))
}
Ok(result) => {
println!("{result}");
(CedarExitCode::Success, result)
}
}
}