use smol_str::SmolStr;
type Node<N> = super::node::Node<Option<N>>;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Policies(pub Vec<Node<Policy>>);
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Annotation {
pub key: Node<Ident>,
pub value: Option<Node<Str>>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Str {
String(SmolStr),
Invalid(SmolStr),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PolicyImpl {
pub annotations: Vec<Node<Annotation>>,
pub effect: Node<Ident>,
pub variables: Vec<Node<VariableDef>>,
pub conds: Vec<Node<Cond>>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Policy {
Policy(PolicyImpl),
#[cfg(feature = "tolerant-ast")]
PolicyError,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct VariableDef {
pub variable: Node<Ident>,
pub unused_type_name: Option<Node<Name>>,
pub entity_type: Option<Node<Add>>,
pub ineq: Option<(RelOp, Node<Expr>)>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Ident {
Principal,
Action,
Resource,
Context,
True,
False,
Permit,
Forbid,
When,
Unless,
In,
Has,
Like,
Is,
If,
Then,
Else,
Ident(SmolStr),
Invalid(String),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Cond {
pub cond: Node<Ident>,
pub expr: Option<Node<Expr>>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ExprImpl {
pub expr: Box<ExprData>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Expr {
Expr(ExprImpl),
#[cfg(feature = "tolerant-ast")]
ErrorExpr,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ExprData {
Or(Node<Or>),
If(Node<Expr>, Node<Expr>, Node<Expr>),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Or {
pub initial: Node<And>,
pub extended: Vec<Node<And>>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct And {
pub initial: Node<Relation>,
pub extended: Vec<Node<Relation>>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Relation {
Common {
initial: Node<Add>,
extended: Vec<(RelOp, Node<Add>)>,
},
Has {
target: Node<Add>,
field: Node<Add>,
},
Like {
target: Node<Add>,
pattern: Node<Add>,
},
IsIn {
target: Node<Add>,
entity_type: Node<Add>,
in_entity: Option<Node<Add>>,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RelOp {
Less,
LessEq,
GreaterEq,
Greater,
NotEq,
Eq,
In,
InvalidSingleEq,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AddOp {
Plus,
Minus,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MultOp {
Times,
Divide,
Mod,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NegOp {
Bang(u8),
OverBang,
Dash(u8),
OverDash,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Add {
pub initial: Node<Mult>,
pub extended: Vec<(AddOp, Node<Mult>)>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Mult {
pub initial: Node<Unary>,
pub extended: Vec<(MultOp, Node<Unary>)>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Unary {
pub op: Option<NegOp>,
pub item: Node<Member>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Member {
pub item: Node<Primary>,
pub access: Vec<Node<MemAccess>>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum MemAccess {
Field(Node<Ident>),
Call(Vec<Node<Expr>>),
Index(Node<Expr>),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Primary {
Literal(Node<Literal>),
Ref(Node<Ref>),
Name(Node<Name>),
Slot(Node<Slot>),
Expr(Node<Expr>),
EList(Vec<Node<Expr>>),
RInits(Vec<Node<RecInit>>),
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Name {
pub path: Vec<Node<Ident>>,
pub name: Node<Ident>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Ref {
Uid {
path: Node<Name>,
eid: Node<Str>,
},
Ref {
path: Node<Name>,
rinits: Vec<Node<RefInit>>,
},
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RefInit(pub Node<Ident>, pub Node<Literal>);
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RecInit(pub Node<Expr>, pub Node<Expr>);
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Literal {
True,
False,
Num(u64),
Str(Node<Str>),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Slot {
Principal,
Resource,
Other(SmolStr),
}
impl Slot {
pub fn matches(&self, var: crate::ast::Var) -> bool {
matches!(
(self, var),
(Slot::Principal, crate::ast::Var::Principal)
| (Slot::Resource, crate::ast::Var::Resource)
)
}
}