1extern crate alloc;
3use alloc::boxed::Box;
4
5use aranya_policy_ast::{Identifier, ResultTypeKind, Span, TypeKind, VType, WithSpanExt as _};
6
7#[derive(Clone, Debug, Eq, PartialEq)]
9pub enum Type<'a> {
10 String,
12 Bytes,
14 Int,
16 Bool,
18 Id,
20 Struct(Identifier),
22 Enum(Identifier),
24 Optional(&'a Type<'a>),
26 Result(&'a Type<'a>, &'a Type<'a>),
28}
29
30impl Type<'_> {
31 #[doc(hidden)]
35 pub const fn const_eq(&self, rhs: &Self) -> bool {
36 use Type::*;
37 match (self, rhs) {
38 (String, String) | (Bytes, Bytes) | (Int, Int) | (Bool, Bool) | (Id, Id) => true,
39 (Struct(lhs), Struct(rhs)) => lhs.const_eq(rhs),
40 (Enum(lhs), Enum(rhs)) => lhs.const_eq(rhs),
41 (Optional(lhs), Optional(rhs)) => lhs.const_eq(rhs),
42 (Result(lhs1, lhs2), Result(rhs1, rhs2)) => lhs1.const_eq(rhs1) && lhs2.const_eq(rhs2),
43 _ => false,
44 }
45 }
46}
47
48impl From<&Type<'_>> for VType {
49 fn from(value: &Type<'_>) -> Self {
50 let kind = match value {
51 Type::String => TypeKind::String,
52 Type::Bytes => TypeKind::Bytes,
53 Type::Int => TypeKind::Int,
54 Type::Bool => TypeKind::Bool,
55 Type::Id => TypeKind::Id,
56 Type::Struct(s) => TypeKind::Struct(s.clone().nowhere()),
57 Type::Enum(e) => TypeKind::Enum(e.clone().nowhere()),
58 Type::Optional(t) => TypeKind::Optional(Box::new((*t).into())),
59 Type::Result(ok, err) => TypeKind::Result(Box::new(ResultTypeKind {
60 ok: (*ok).into(),
61 err: (*err).into(),
62 })),
63 };
64 Self {
65 inner: kind,
66 span: Span::empty(),
67 }
68 }
69}
70
71#[derive(Clone, Debug)]
73pub enum Color<'a> {
74 Pure(Type<'a>),
77 Finish,
80}
81
82#[derive(Clone, Debug)]
84pub struct Func<'a> {
85 pub name: Identifier,
87 pub args: &'a [Arg<'a>],
89 pub return_type: Type<'a>,
91}
92
93#[derive(Clone, Debug, PartialEq, Eq)]
95pub struct Arg<'a> {
96 pub name: Identifier,
98 pub vtype: Type<'a>,
100}
101
102pub struct Struct<'a> {
104 pub name: Identifier,
106 pub fields: &'a [Arg<'a>],
108}
109
110pub struct Enum<'a> {
112 pub name: Identifier,
114 pub variants: &'a [Identifier],
116}
117
118#[macro_export]
189macro_rules! arg {
190 ($name:literal, String) => {{
191 $crate::__arg!($name, String)
192 }};
193 ($name:literal, Bytes) => {{
194 $crate::__arg!($name, Bytes)
195 }};
196 ($name:literal, Int) => {{
197 $crate::__arg!($name, Int)
198 }};
199 ($name:literal, Bool) => {{
200 $crate::__arg!($name, Bool)
201 }};
202 ($name:literal, Id) => {{
203 $crate::__arg!($name, Id)
204 }};
205 ($name:literal, Struct($struct_name:literal)) => {{
206 $crate::__arg!($name, Struct($struct_name))
207 }};
208 ($name:literal, Enum($enum_name:literal)) => {{
209 $crate::__arg!($name, Enum($enum_name))
210 }};
211 ($name:literal, Optional($(inner:tt)+)) => {{
212 $crate::__arg!($name, Optional($(inner)+))
213 }};
214 ($name:literal, Optional($inner:expr)) => {{
215 $crate::__arg!($name, Optional($inner))
216 }};
217 ($name:literal, Result($ok:expr, $err:expr)) => {{
218 $crate::__arg!($name, Result($ok, $err))
219 }};
220 ($name:literal, $type:ident) => {{
221 ::core::compile_error!(::core::concat!(
222 "unknown argument type: ",
223 ::core::stringify!($type)
224 ))
225 }};
226}
227
228#[doc(hidden)]
229#[macro_export]
230macro_rules! __arg {
231 ($name:literal, $type:ident) => {{
232 $crate::ffi::Arg {
233 name: $crate::ast::ident!($name),
234 vtype: $crate::__type!($type),
235 }
236 }};
237 ($name:literal, Struct($struct_name:literal)) => {{
238 $crate::ffi::Arg {
239 name: $crate::ast::ident!($name),
240 vtype: $crate::__type!(Struct($struct_name)),
241 }
242 }};
243 ($name:literal, Enum($enum_name:literal)) => {{
244 $crate::ffi::Arg {
245 name: $crate::ast::ident!($name),
246 vtype: $crate::__type!(Enum($enum_name)),
247 }
248 }};
249 ($name:literal, Optional($inner:expr)) => {{
250 $crate::ffi::Arg {
251 name: $crate::ast::ident!($name),
252 vtype: $crate::__type!(Optional($inner)),
253 }
254 }};
255 ($name:literal, Result($ok:expr, $err:expr)) => {{
256 $crate::ffi::Arg {
257 name: $crate::ast::ident!($name),
258 vtype: $crate::__type!(Result($ok, $err)),
259 }
260 }};
261}
262
263#[doc(hidden)]
264#[macro_export]
265macro_rules! __type {
266 (@raw $type:ident) => {
267 $crate::ffi::Type::$type
268 };
269 (@raw Struct($struct_name:literal)) => {
270 $crate::ffi::Type::Struct($crate::ast::ident!($struct_name))
271 };
272 (@raw Enum($enum_name:literal)) => {
273 $crate::ffi::Type::Enum($crate::ast::ident!($enum_name))
274 };
275 (@raw Optional($inner:expr)) => {
276 $crate::ffi::Type::Optional($inner)
277 };
278 (@raw Result($ok:expr, $err:expr)) => {
279 $crate::ffi::Type::Result($ok, $err)
280 };
281
282 (String) => {{ $crate::__type!(@raw String) }};
283 (Bytes) => {{ $crate::__type!(@raw Bytes) }};
284 (Int) => {{ $crate::__type!(@raw Int) }};
285 (Bool) => {{ $crate::__type!(@raw Bool) }};
286 (Id) => {{ $crate::__type!(@raw Id) }};
287 (Struct($struct_name:literal)) => {{
288 $crate::__type!(@raw Struct($struct_name))
289 }};
290 (Enum($enum_name:literal)) => {{
291 $crate::__type!(@raw Enum($enum_name))
292 }};
293 (Optional($(inner:tt)+)) => {{
294 $crate::__type!(@raw Optional($(inner)+))
295 }};
296 (Optional($inner:expr)) => {{
297 $crate::__type!(@raw Optional($inner))
298 }};
299 (Result($ok:expr, $err:expr)) => {{
300 $crate::__type!(@raw Result($ok, $err))
301 }};
302 ($type:ident) => {{
303 ::core::compile_error!(::core::concat!(
304 "unknown argument type: ",
305 ::core::stringify!($type)
306 ))
307 }};
308}
309
310pub struct ModuleSchema<'a> {
312 pub name: Identifier,
314 pub functions: &'a [Func<'a>],
316 pub structs: &'a [Struct<'a>],
318 pub enums: &'a [Enum<'a>],
320}