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::{Identifier, ResultTypeKind, Text, TypeKind, WithSpanExt as _};
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(name.to_owned().nowhere()),
60            Self::Struct(s) => TypeKind::Struct(s.name.clone().nowhere()),
61            Self::Option(o) => {
62                let inner_kind = match o {
63                    Some(inner_value) => inner_value.vtype(),
64                    None => TypeKind::Never,
65                };
66                TypeKind::Optional(Box::new(inner_kind.nowhere()))
67            }
68            Self::Result(Ok(ok)) => {
69                let ok_kind = ok.vtype();
70                TypeKind::Result(Box::new(ResultTypeKind {
71                    ok: ok_kind.nowhere(),
72                    err: TypeKind::Never.nowhere(),
73                }))
74            }
75            Self::Result(Err(err)) => {
76                let err_kind = err.vtype();
77                TypeKind::Result(Box::new(ResultTypeKind {
78                    ok: TypeKind::Never.nowhere(),
79                    err: err_kind.nowhere(),
80                }))
81            }
82        }
83    }
84
85    /// Returns a string representing the value's type.
86    pub fn type_name(&self) -> String {
87        match self {
88            Self::Int(_) => String::from("Int"),
89            Self::Bool(_) => String::from("Bool"),
90            Self::String(_) => String::from("String"),
91            Self::Struct(s) => format!("Struct {}", s.name),
92            Self::Enum(name, _) => format!("Enum {}", name),
93            Self::Option(Some(inner)) => format!("Option[{}]", inner.type_name()),
94            Self::Option(None) => String::from("Option[_]"),
95            Self::Result(Ok(inner)) => format!("Result[_, {}]", inner.type_name()),
96            Self::Result(Err(inner)) => format!("Result[{}, _]", inner.type_name()),
97        }
98    }
99}
100
101impl Display for ConstValue {
102    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103        match self {
104            Self::Int(i) => write!(f, "{}", i),
105            Self::Bool(b) => write!(f, "{}", b),
106            Self::String(s) => write!(f, "\"{}\"", s),
107            Self::Struct(s) => s.fmt(f),
108            Self::Enum(name, value) => write!(f, "{name}::{value}"),
109            Self::Option(Some(v)) => write!(f, "Some({v})"),
110            Self::Option(None) => write!(f, "None"),
111            Self::Result(Ok(v)) => write!(f, "Ok({})", v),
112            Self::Result(Err(v)) => write!(f, "Err({})", v),
113        }
114    }
115}
116
117/// A Struct value
118#[derive(
119    Debug,
120    Clone,
121    PartialEq,
122    Eq,
123    Serialize,
124    Deserialize,
125    rkyv::Archive,
126    rkyv::Deserialize,
127    rkyv::Serialize,
128)]
129#[rkyv(serialize_bounds(
130    __S: rkyv::ser::Writer + rkyv::ser::Allocator,
131    __S::Error: rkyv::rancor::Source,
132))]
133#[rkyv(deserialize_bounds(__D::Error: rkyv::rancor::Source))]
134#[rkyv(bytecheck(
135    bounds(
136        __C: rkyv::validation::ArchiveContext,
137        __C::Error: rkyv::rancor::Source,
138    )
139))]
140pub struct ConstStruct {
141    /// The name of the struct
142    pub name: Identifier,
143    /// the fields of the struct
144    #[rkyv(omit_bounds)]
145    pub fields: BTreeMap<Identifier, ConstValue>,
146}
147
148impl ConstStruct {
149    /// Creates an empty struct.
150    pub fn empty(name: Identifier) -> Self {
151        Self {
152            name,
153            fields: BTreeMap::new(),
154        }
155    }
156}
157
158impl Display for ConstStruct {
159    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
160        write!(f, "{}{{", self.name)?;
161        let mut i = false;
162        for (k, v) in &self.fields {
163            if i {
164                write!(f, ", ")?;
165            }
166            i = true;
167            write!(f, "{}: {}", k, v)?;
168        }
169        write!(f, "}}")
170    }
171}