actix_security_core/http/security/expression/ast.rs
1//! Abstract Syntax Tree for security expressions.
2
3/// Binary operators for combining expressions.
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub enum BinaryOp {
6 /// Logical AND (both must be true)
7 And,
8 /// Logical OR (at least one must be true)
9 Or,
10}
11
12/// Unary operators for modifying expressions.
13#[derive(Debug, Clone, PartialEq, Eq)]
14pub enum UnaryOp {
15 /// Logical NOT (inverts the result)
16 Not,
17}
18
19/// A security expression AST node.
20#[derive(Debug, Clone, PartialEq)]
21pub enum Expression {
22 /// A boolean literal (true/false)
23 Boolean(bool),
24
25 /// A function call with name and arguments
26 /// e.g., `hasRole('ADMIN')` -> Function("hasRole", vec!["ADMIN"])
27 Function { name: String, args: Vec<String> },
28
29 /// A binary operation combining two expressions
30 /// e.g., `hasRole('ADMIN') AND hasRole('USER')`
31 Binary {
32 left: Box<Expression>,
33 op: BinaryOp,
34 right: Box<Expression>,
35 },
36
37 /// A unary operation on an expression
38 /// e.g., `NOT hasRole('ADMIN')`
39 Unary { op: UnaryOp, expr: Box<Expression> },
40
41 /// A grouped expression (parentheses)
42 /// e.g., `(hasRole('ADMIN') OR hasRole('USER'))`
43 Group(Box<Expression>),
44}
45
46impl Expression {
47 /// Creates a new function expression.
48 pub fn function(name: impl Into<String>, args: Vec<String>) -> Self {
49 Expression::Function {
50 name: name.into(),
51 args,
52 }
53 }
54
55 /// Creates a new AND expression.
56 pub fn and(left: Expression, right: Expression) -> Self {
57 Expression::Binary {
58 left: Box::new(left),
59 op: BinaryOp::And,
60 right: Box::new(right),
61 }
62 }
63
64 /// Creates a new OR expression.
65 pub fn or(left: Expression, right: Expression) -> Self {
66 Expression::Binary {
67 left: Box::new(left),
68 op: BinaryOp::Or,
69 right: Box::new(right),
70 }
71 }
72
73 /// Creates a new NOT expression.
74 #[allow(clippy::should_implement_trait)]
75 pub fn not(expr: Expression) -> Self {
76 Expression::Unary {
77 op: UnaryOp::Not,
78 expr: Box::new(expr),
79 }
80 }
81
82 /// Creates a grouped expression.
83 pub fn group(expr: Expression) -> Self {
84 Expression::Group(Box::new(expr))
85 }
86}