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 {
28 name: String,
29 args: Vec<String>,
30 },
31
32 /// A binary operation combining two expressions
33 /// e.g., `hasRole('ADMIN') AND hasRole('USER')`
34 Binary {
35 left: Box<Expression>,
36 op: BinaryOp,
37 right: Box<Expression>,
38 },
39
40 /// A unary operation on an expression
41 /// e.g., `NOT hasRole('ADMIN')`
42 Unary {
43 op: UnaryOp,
44 expr: Box<Expression>,
45 },
46
47 /// A grouped expression (parentheses)
48 /// e.g., `(hasRole('ADMIN') OR hasRole('USER'))`
49 Group(Box<Expression>),
50}
51
52impl Expression {
53 /// Creates a new function expression.
54 pub fn function(name: impl Into<String>, args: Vec<String>) -> Self {
55 Expression::Function {
56 name: name.into(),
57 args,
58 }
59 }
60
61 /// Creates a new AND expression.
62 pub fn and(left: Expression, right: Expression) -> Self {
63 Expression::Binary {
64 left: Box::new(left),
65 op: BinaryOp::And,
66 right: Box::new(right),
67 }
68 }
69
70 /// Creates a new OR expression.
71 pub fn or(left: Expression, right: Expression) -> Self {
72 Expression::Binary {
73 left: Box::new(left),
74 op: BinaryOp::Or,
75 right: Box::new(right),
76 }
77 }
78
79 /// Creates a new NOT expression.
80 #[allow(clippy::should_implement_trait)]
81 pub fn not(expr: Expression) -> Self {
82 Expression::Unary {
83 op: UnaryOp::Not,
84 expr: Box::new(expr),
85 }
86 }
87
88 /// Creates a grouped expression.
89 pub fn group(expr: Expression) -> Self {
90 Expression::Group(Box::new(expr))
91 }
92}