Skip to main content

aranya_policy_module/
module.rs

1//! Serializable [`Machine`][super::machine::Machine] state.
2
3extern crate alloc;
4
5use alloc::{boxed::Box, collections::BTreeMap, vec::Vec};
6use core::fmt::{self, Display};
7
8use aranya_policy_ast::{self as ast, Identifier, Param};
9use serde::{Deserialize, Serialize};
10
11use crate::{
12    CodeMap, Instruction, Label, Value,
13    named::{NamedMap, named},
14};
15
16/// Identifies a [`Module`].
17#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
18pub enum Version {
19    /// Version 0.
20    V0,
21}
22
23impl Version {
24    /// Returns the `Version` as a human-readable string.
25    pub const fn as_str(&self) -> &'static str {
26        match self {
27            Self::V0 => "V0",
28        }
29    }
30}
31
32impl Display for Version {
33    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34        f.write_str(self.as_str())
35    }
36}
37
38/// Unsupported [`Module`] version.
39#[derive(Debug, Eq, PartialEq, thiserror::Error)]
40#[error("unsupported module version")]
41pub struct UnsupportedVersion(());
42
43/// The serializable state of
44/// a [`Machine`](../policy_vm/struct.Machine.html).
45#[derive(
46    Clone,
47    Debug,
48    Serialize,
49    Deserialize,
50    Eq,
51    PartialEq,
52    rkyv::Archive,
53    rkyv::Deserialize,
54    rkyv::Serialize,
55)]
56pub struct Module {
57    /// The module data
58    pub data: ModuleData,
59    // TODO(eric): add a checksum?
60}
61
62impl Module {
63    /// Returns the module version.
64    pub const fn version(&self) -> Version {
65        match self.data {
66            ModuleData::V0(_) => Version::V0,
67        }
68    }
69}
70
71/// Versioned [`Module`] data.
72#[derive(
73    Clone,
74    Debug,
75    Eq,
76    PartialEq,
77    Serialize,
78    Deserialize,
79    rkyv::Archive,
80    rkyv::Deserialize,
81    rkyv::Serialize,
82)]
83#[serde(tag = "version")]
84pub enum ModuleData {
85    /// Version 0
86    V0(ModuleV0),
87}
88
89/// The Version 0 module format
90#[derive(
91    Clone,
92    Debug,
93    Eq,
94    PartialEq,
95    Serialize,
96    Deserialize,
97    rkyv::Archive,
98    rkyv::Deserialize,
99    rkyv::Serialize,
100)]
101#[serde(deny_unknown_fields)]
102pub struct ModuleV0 {
103    /// Program memory
104    pub progmem: Box<[Instruction]>,
105    /// Labels
106    pub labels: BTreeMap<Label, usize>,
107    /// Action definitions
108    pub action_defs: NamedMap<ActionDef>,
109    /// Command definitions
110    pub command_defs: NamedMap<CommandDef>,
111    /// Fact definitions
112    pub fact_defs: BTreeMap<Identifier, ast::FactDefinition>,
113    /// Struct definitions
114    pub struct_defs: BTreeMap<Identifier, Vec<ast::FieldDefinition>>,
115    /// Enum definitions
116    pub enum_defs: BTreeMap<Identifier, BTreeMap<Identifier, i64>>,
117    /// Code map
118    pub codemap: Option<CodeMap>,
119    /// Global static data
120    pub globals: BTreeMap<Identifier, Value>,
121}
122
123/// An action definition.
124#[derive(
125    Clone,
126    Debug,
127    Eq,
128    PartialEq,
129    Serialize,
130    Deserialize,
131    rkyv::Archive,
132    rkyv::Deserialize,
133    rkyv::Serialize,
134)]
135pub struct ActionDef {
136    /// The name of the action.
137    pub name: ast::Ident,
138    /// The persistence of the action.
139    pub persistence: ast::Persistence,
140    /// The parameters of the action.
141    pub params: NamedMap<Param>,
142}
143named!(ActionDef);
144
145/// A command definition.
146#[derive(
147    Clone,
148    Debug,
149    Eq,
150    PartialEq,
151    Serialize,
152    Deserialize,
153    rkyv::Archive,
154    rkyv::Deserialize,
155    rkyv::Serialize,
156)]
157pub struct CommandDef {
158    /// The name of the command.
159    pub name: ast::Ident,
160    /// The persistence of the command.
161    pub persistence: ast::Persistence,
162    /// The attributes of the command.
163    pub attributes: NamedMap<Attribute>,
164    /// The fields of the command.
165    pub fields: NamedMap<Field>,
166}
167named!(CommandDef);
168
169/// A command attribute.
170#[derive(
171    Clone,
172    Debug,
173    Eq,
174    PartialEq,
175    Serialize,
176    Deserialize,
177    rkyv::Archive,
178    rkyv::Deserialize,
179    rkyv::Serialize,
180)]
181pub struct Attribute {
182    /// The name of the attribute.
183    pub name: ast::Ident,
184    /// The value of the attribute.
185    pub value: Value,
186}
187named!(Attribute);
188
189/// A struct or command field.
190#[derive(
191    Clone,
192    Debug,
193    Eq,
194    PartialEq,
195    Serialize,
196    Deserialize,
197    rkyv::Archive,
198    rkyv::Deserialize,
199    rkyv::Serialize,
200)]
201pub struct Field {
202    /// The name of the field
203    pub name: ast::Ident,
204    /// The type of the field
205    pub ty: ast::VType,
206}
207named!(Field);