Skip to main content

aranya_policy_module/
data.rs

1extern crate alloc;
2
3use alloc::{borrow::ToOwned as _, boxed::Box, collections::BTreeMap, format, string::String};
4use core::fmt::{self, Display};
5
6use aranya_policy_ast::{Ident, Identifier, ResultTypeKind, Span, Text, TypeKind, VType};
7use serde::{Deserialize, Serialize};
8
9/// A constant or literal value used in policy.
10#[derive(
11    Debug,
12    Clone,
13    PartialEq,
14    Eq,
15    Serialize,
16    Deserialize,
17    rkyv::Archive,
18    rkyv::Deserialize,
19    rkyv::Serialize,
20)]
21#[rkyv(serialize_bounds(
22    __S: rkyv::ser::Writer + rkyv::ser::Allocator,
23    __S::Error: rkyv::rancor::Source,
24))]
25#[rkyv(deserialize_bounds(__D::Error: rkyv::rancor::Source))]
26#[rkyv(bytecheck(
27    bounds(
28        __C: rkyv::validation::ArchiveContext,
29        __C::Error: rkyv::rancor::Source,
30    )
31))]
32pub enum ConstValue {
33    /// Integer (64-bit signed)
34    Int(i64),
35    /// Boolean
36    Bool(bool),
37    /// String (UTF-8)
38    String(Text),
39    /// Struct
40    Struct(#[rkyv(omit_bounds)] ConstStruct),
41    /// Enumeration value
42    Enum(Identifier, i64),
43    /// Optional value
44    Option(#[rkyv(omit_bounds)] Option<Box<Self>>),
45    /// Result value
46    Result(#[rkyv(omit_bounds)] Result<Box<Self>, Box<Self>>),
47}
48
49impl ConstValue {
50    /// Shorthand for `Self::Option(None)`.
51    pub const NONE: Self = Self::Option(None);
52
53    /// Get the associated [`TypeKind`].
54    pub fn vtype(&self) -> TypeKind {
55        match self {
56            Self::Int(_) => TypeKind::Int,
57            Self::Bool(_) => TypeKind::Bool,
58            Self::String(_) => TypeKind::String,
59            Self::Enum(name, _) => TypeKind::Enum(Ident {
60                name: name.to_owned(),
61                span: Span::empty(),
62            }),
63            Self::Struct(s) => TypeKind::Struct(Ident {
64                name: s.name.clone(),
65                span: Span::empty(),
66            }),
67            Self::Option(o) => {
68                let inner_kind = match o {
69                    Some(inner_value) => inner_value.vtype(),
70                    None => TypeKind::Never,
71                };
72                TypeKind::Optional(Box::new(VType {
73                    kind: inner_kind,
74                    span: Span::empty(),
75                }))
76            }
77            Self::Result(Ok(ok)) => {
78                let ok_kind = ok.vtype();
79                TypeKind::Result(Box::new(ResultTypeKind {
80                    ok: VType {
81                        kind: ok_kind,
82                        span: Span::empty(),
83                    },
84                    err: VType {
85                        kind: TypeKind::Never,
86                        span: Span::empty(),
87                    },
88                }))
89            }
90            Self::Result(Err(err)) => {
91                let err_kind = err.vtype();
92                TypeKind::Result(Box::new(ResultTypeKind {
93                    ok: VType {
94                        kind: TypeKind::Never,
95                        span: Span::empty(),
96                    },
97                    err: VType {
98                        kind: err_kind,
99                        span: Span::empty(),
100                    },
101                }))
102            }
103        }
104    }
105
106    /// Returns a string representing the value's type.
107    pub fn type_name(&self) -> String {
108        match self {
109            Self::Int(_) => String::from("Int"),
110            Self::Bool(_) => String::from("Bool"),
111            Self::String(_) => String::from("String"),
112            Self::Struct(s) => format!("Struct {}", s.name),
113            Self::Enum(name, _) => format!("Enum {}", name),
114            Self::Option(Some(inner)) => format!("Option[{}]", inner.type_name()),
115            Self::Option(None) => String::from("Option[_]"),
116            Self::Result(Ok(inner)) => format!("Result[_, {}]", inner.type_name()),
117            Self::Result(Err(inner)) => format!("Result[{}, _]", inner.type_name()),
118        }
119    }
120}
121
122impl Display for ConstValue {
123    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
124        match self {
125            Self::Int(i) => write!(f, "{}", i),
126            Self::Bool(b) => write!(f, "{}", b),
127            Self::String(s) => write!(f, "\"{}\"", s),
128            Self::Struct(s) => s.fmt(f),
129            Self::Enum(name, value) => write!(f, "{name}::{value}"),
130            Self::Option(Some(v)) => write!(f, "Some({v})"),
131            Self::Option(None) => write!(f, "None"),
132            Self::Result(Ok(v)) => write!(f, "Ok({})", v),
133            Self::Result(Err(v)) => write!(f, "Err({})", v),
134        }
135    }
136}
137
138/// A Struct value
139#[derive(
140    Debug,
141    Clone,
142    PartialEq,
143    Eq,
144    Serialize,
145    Deserialize,
146    rkyv::Archive,
147    rkyv::Deserialize,
148    rkyv::Serialize,
149)]
150#[rkyv(serialize_bounds(
151    __S: rkyv::ser::Writer + rkyv::ser::Allocator,
152    __S::Error: rkyv::rancor::Source,
153))]
154#[rkyv(deserialize_bounds(__D::Error: rkyv::rancor::Source))]
155#[rkyv(bytecheck(
156    bounds(
157        __C: rkyv::validation::ArchiveContext,
158        __C::Error: rkyv::rancor::Source,
159    )
160))]
161pub struct ConstStruct {
162    /// The name of the struct
163    pub name: Identifier,
164    /// the fields of the struct
165    #[rkyv(omit_bounds)]
166    pub fields: BTreeMap<Identifier, ConstValue>,
167}
168
169impl ConstStruct {
170    /// Creates an empty struct.
171    pub fn empty(name: Identifier) -> Self {
172        Self {
173            name,
174            fields: BTreeMap::new(),
175        }
176    }
177}
178
179impl Display for ConstStruct {
180    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
181        write!(f, "{}{{", self.name)?;
182        let mut i = false;
183        for (k, v) in &self.fields {
184            if i {
185                write!(f, ", ")?;
186            }
187            i = true;
188            write!(f, "{}: {}", k, v)?;
189        }
190        write!(f, "}}")
191    }
192}