use std::collections::HashSet;
use crate::{
ast::{EntityUID, Expr, PolicyID, SlotEnv},
parser::parse_expr,
tpe::request::{PartialEntityUID, PartialRequest},
validator::{typecheck::Typechecker, types::Type, ValidationMode, ValidatorSchema},
};
#[track_caller]
pub(crate) fn parse_partial_euid(s: &str) -> PartialEntityUID {
if let Ok(euid) = s.parse::<EntityUID>() {
PartialEntityUID::from(euid)
} else {
PartialEntityUID {
ty: s.parse().expect("should parse as an entity type"),
eid: None,
}
}
}
#[track_caller]
pub(crate) fn parse_typed_expr(
expr_str: &str,
request: &PartialRequest,
schema: &ValidatorSchema,
slot_env: &SlotEnv,
) -> Expr<Option<Type>> {
let env = request
.find_request_env(&schema)
.unwrap()
.link_slot_env(slot_env);
let expr = match parse_expr(expr_str) {
Ok(expr) => expr,
Err(es) => {
for e in es {
println!("{:?}", miette::Report::new(e));
}
panic!("parse error on input expression");
}
};
let mut type_errors = HashSet::new();
let id = PolicyID::from_string("test");
let ans = Typechecker::new(schema, ValidationMode::Strict).typecheck_expr_with_request_env(
&env,
&expr,
&id,
&mut type_errors,
);
if !type_errors.is_empty() {
println!("got {} type errors", type_errors.len());
for e in type_errors {
println!("{:?}", miette::Report::new(e));
}
panic!("unexpected type error in expression")
}
ans.into_typed_expr()
.expect("expected typechecking to produce a typed expression")
}