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#[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 Int(i64),
35 Bool(bool),
37 String(Text),
39 Struct(#[rkyv(omit_bounds)] ConstStruct),
41 Enum(Identifier, i64),
43 Option(#[rkyv(omit_bounds)] Option<Box<Self>>),
45 Result(#[rkyv(omit_bounds)] Result<Box<Self>, Box<Self>>),
47}
48
49impl ConstValue {
50 pub const NONE: Self = Self::Option(None);
52
53 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 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#[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 pub name: Identifier,
143 #[rkyv(omit_bounds)]
145 pub fields: BTreeMap<Identifier, ConstValue>,
146}
147
148impl ConstStruct {
149 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}