use std::{path::PathBuf, str::FromStr};
use cedar_policy::Expression;
use clap::Args;
use miette::Report;
use crate::{load_entities, CedarExitCode, OptionalPoliciesArgs, OptionalSchemaArgs, PoliciesArgs};
#[derive(Args, Debug)]
pub struct CheckParseArgs {
#[command(flatten)]
pub policies: OptionalPoliciesArgs,
#[arg(long)]
pub expression: Option<String>,
#[command(flatten)]
pub schema: OptionalSchemaArgs,
#[arg(long = "entities", value_name = "FILE")]
pub entities_file: Option<PathBuf>,
}
pub fn check_parse(args: &CheckParseArgs) -> CedarExitCode {
if args.policies.policies_file.is_none()
&& args.schema.schema_file.is_none()
&& args.entities_file.is_none()
&& args.expression.is_none()
{
let pargs = PoliciesArgs {
policies_file: None, policy_format: args.policies.policy_format,
template_linked_file: args.policies.template_linked_file.clone(),
};
match pargs.get_policy_set() {
Ok(_) => return CedarExitCode::Success,
Err(e) => {
println!("{e:?}");
return CedarExitCode::Failure;
}
}
}
#[expect(
clippy::useless_let_if_seq,
reason = "exit_code is mutated by later expressions"
)]
let mut exit_code = CedarExitCode::Success;
if let Err(e) = args.policies.get_policy_set() {
println!("{e:?}");
exit_code = CedarExitCode::Failure;
}
if let Some(e) = args
.expression
.as_ref()
.and_then(|expr| Expression::from_str(expr).err())
{
println!("{:?}", Report::new(e));
exit_code = CedarExitCode::Failure;
}
let schema = match args.schema.get_schema() {
Ok(schema) => schema,
Err(e) => {
println!("{e:?}");
exit_code = CedarExitCode::Failure;
None
}
};
if let Some(e) = args
.entities_file
.as_ref()
.and_then(|e| load_entities(e, schema.as_ref()).err())
{
println!("{e:?}");
exit_code = CedarExitCode::Failure;
}
exit_code
}