cedar_policy_core/ast/
ops.rs

1/*
2 * Copyright 2022-2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17use crate::ast::{CallStyle, Name};
18use serde::{Deserialize, Serialize};
19
20/// Built-in operators with exactly one argument
21#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Copy, Hash)]
22#[cfg_attr(fuzzing, derive(arbitrary::Arbitrary))]
23pub enum UnaryOp {
24    /// Logical negation
25    ///
26    /// Argument must have Bool type
27    Not,
28    /// Integer negation
29    ///
30    /// Argument must have Long type
31    Neg,
32}
33
34/// Built-in operators with exactly two arguments
35#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Copy, Hash)]
36#[cfg_attr(fuzzing, derive(arbitrary::Arbitrary))]
37pub enum BinaryOp {
38    /// Equality
39    ///
40    /// Works on arguments of any type, ie "total equality". If you compare
41    /// things of different types, `Eq` will return `false`, rather than error.
42    Eq,
43
44    /// <
45    ///
46    /// Arguments must have Long type
47    Less,
48
49    /// <=
50    ///
51    /// Arguments must have Long type
52    LessEq,
53
54    /// Integer addition
55    ///
56    /// Arguments must have Long type
57    Add,
58
59    /// Integer subtraction
60    ///
61    /// Arguments must have Long type
62    Sub,
63
64    /// Hierarchy membership. Specifically, is the first arg a member of the
65    /// second.
66    ///
67    /// First argument must have Entity type.
68    /// Second argument must either have Entity type, or Set type where the
69    /// set elements all have Entity type. If it's a set, the semantics is
70    /// "is the first argument `in` any element of the given set"
71    In,
72
73    /// Set membership.
74    ///
75    /// First argument must have Set type.
76    Contains,
77
78    /// ContainsAll test for sets. Specifically, if the first set contains the second arg.
79    ///
80    /// Arguments must have Set type
81    ContainsAll,
82
83    /// ContainsAny test for sets (is the intersection empty?)
84    ///
85    /// Arguments must have Set type
86    ContainsAny,
87}
88
89/// Extension functions
90/// Clone is O(1).
91#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Hash)]
92pub struct ExtensionFunctionOp {
93    /// Name of the function being called
94    pub function_name: Name,
95}
96
97impl std::fmt::Display for UnaryOp {
98    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99        match self {
100            UnaryOp::Not => write!(f, "!_"),
101            UnaryOp::Neg => write!(f, "-_"),
102        }
103    }
104}
105
106impl std::fmt::Display for BinaryOp {
107    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
108        match self {
109            BinaryOp::Eq => write!(f, "_==_"),
110            BinaryOp::Less => write!(f, "_<_"),
111            BinaryOp::LessEq => write!(f, "_<=_"),
112            BinaryOp::Add => write!(f, "_+_"),
113            BinaryOp::Sub => write!(f, "_-_"),
114            BinaryOp::In => write!(f, "_in_"),
115            BinaryOp::Contains => write!(f, "contains"),
116            BinaryOp::ContainsAll => write!(f, "containsAll"),
117            BinaryOp::ContainsAny => write!(f, "containsAny"),
118        }
119    }
120}
121
122impl std::fmt::Display for ExtensionFunctionOp {
123    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
124        write!(f, "{}", self.function_name)
125    }
126}
127
128impl std::fmt::Display for CallStyle {
129    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
130        match self {
131            Self::FunctionStyle => write!(f, "function-style"),
132            Self::MethodStyle => write!(f, "method-style"),
133        }
134    }
135}