cedar_policy_core/ast/
literal.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::{EntityUID, StaticallyTyped, Type};
18use serde::{Deserialize, Serialize};
19use smol_str::SmolStr;
20use std::sync::Arc;
21
22/// First-class values which may appear as literals in `Expr::Lit`.
23///
24/// Note that the auto-derived `PartialEq` and `Eq` are total equality -- using
25/// == to compare `Literal`s of different types results in `false`, not a type
26/// error.
27///
28/// `Literal` does not include set or record types. Although Cedar has syntax
29/// for set literals (e.g., [2, -7, 8]), these can include arbitrary
30/// expressions (e.g., [2+3, principal.foo]), so they have to become
31/// `Expr::Set`, not `Expr::Lit`.
32///
33/// Cloning is O(1).
34#[derive(Serialize, Deserialize, Hash, Debug, PartialEq, Eq, Clone, PartialOrd, Ord)]
35pub enum Literal {
36    /// Boolean value
37    Bool(bool),
38    /// Signed integer value
39    Long(i64),
40    /// String value
41    String(SmolStr),
42    /// Entity, represented by its UID. To get the actual `Entity`, you have to
43    /// look up this UID in a Store or Slice.
44    EntityUID(Arc<EntityUID>),
45}
46
47impl StaticallyTyped for Literal {
48    fn type_of(&self) -> Type {
49        match self {
50            Self::Bool(_) => Type::Bool,
51            Self::Long(_) => Type::Long,
52            Self::String(_) => Type::String,
53            Self::EntityUID(uid) => uid.type_of(),
54        }
55    }
56}
57
58impl std::fmt::Display for Literal {
59    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60        match self {
61            Self::Bool(b) => write!(f, "{}", b),
62            Self::Long(i) => write!(f, "{}", i),
63            // print string literals after the `escape_debug` transformation
64            // note that it adds backslashes for more characters than we may want,
65            // e.g., a single quote is printed as `\'`.
66            Self::String(s) => write!(f, "\"{}\"", s.escape_debug()),
67            Self::EntityUID(uid) => write!(f, "{}", uid),
68        }
69    }
70}
71
72/// Create a Literal directly from a bool
73impl From<bool> for Literal {
74    fn from(b: bool) -> Self {
75        Self::Bool(b)
76    }
77}
78
79/// Create a Literal directly from an i64
80impl From<i64> for Literal {
81    fn from(i: i64) -> Self {
82        Self::Long(i)
83    }
84}
85
86/// Create a Literal directly from a String
87impl From<String> for Literal {
88    fn from(s: String) -> Self {
89        Self::String(SmolStr::new(s))
90    }
91}
92
93/// Create a Literal directly from an &str
94impl From<&str> for Literal {
95    fn from(s: &str) -> Self {
96        Self::String(SmolStr::new(s))
97    }
98}
99
100impl From<SmolStr> for Literal {
101    fn from(s: SmolStr) -> Self {
102        Self::String(s)
103    }
104}
105
106/// Create a Literal directly from an EntityUID
107impl From<EntityUID> for Literal {
108    fn from(e: EntityUID) -> Self {
109        Self::EntityUID(Arc::new(e))
110    }
111}
112
113impl From<Arc<EntityUID>> for Literal {
114    fn from(ptr: Arc<EntityUID>) -> Self {
115        Self::EntityUID(ptr)
116    }
117}
118
119impl Literal {
120    /// Check if this literal is an entity reference
121    ///
122    /// This is used for policy headers, where some syntax is
123    /// required to be an entity reference.
124    pub fn is_ref(&self) -> bool {
125        matches!(self, Self::EntityUID(..))
126    }
127}