Skip to main content

interstice_abi/schema/
module.rs

1use crate::{
2    ABI_VERSION, Authority, IntersticeType, ModuleDependency, NodeDependency, ReducerSchema,
3    SubscriptionSchema, TableSchema, TableVisibility, Version,
4    interstice_type_def::IntersticeTypeDef,
5};
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8
9#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
10pub enum ModuleVisibility {
11    // Visible to all other nodes
12    Public,
13    // Only visible for local modules on the current node
14    Private,
15}
16
17#[derive(Debug, Clone, Deserialize, Serialize)]
18pub struct ModuleSchema {
19    pub abi_version: u16,
20    pub name: String,
21    pub version: Version,
22    pub visibility: ModuleVisibility,
23    pub reducers: Vec<ReducerSchema>,
24    pub tables: Vec<TableSchema>,
25    pub subscriptions: Vec<SubscriptionSchema>,
26    pub type_definitions: HashMap<String, IntersticeTypeDef>,
27    pub authorities: Vec<Authority>,
28    pub module_dependencies: Vec<ModuleDependency>,
29    pub node_dependencies: Vec<NodeDependency>,
30}
31
32impl ModuleSchema {
33    pub fn empty() -> Self {
34        Self {
35            abi_version: 0,
36            name: "".into(),
37            version: Version {
38                major: 0,
39                minor: 0,
40                patch: 0,
41            },
42            visibility: ModuleVisibility::Private,
43            reducers: Vec::new(),
44            tables: Vec::new(),
45            subscriptions: Vec::new(),
46            type_definitions: HashMap::new(),
47            authorities: Vec::new(),
48            module_dependencies: Vec::new(),
49            node_dependencies: Vec::new(),
50        }
51    }
52
53    pub fn new(
54        name: impl Into<String>,
55        version: Version,
56        visibility: ModuleVisibility,
57        reducers: Vec<ReducerSchema>,
58        tables: Vec<TableSchema>,
59        subscriptions: Vec<SubscriptionSchema>,
60        type_definitions: HashMap<String, IntersticeTypeDef>,
61        authorities: Vec<Authority>,
62        module_dependencies: Vec<ModuleDependency>,
63        node_dependencies: Vec<NodeDependency>,
64    ) -> Self {
65        Self {
66            abi_version: ABI_VERSION,
67            name: name.into(),
68            visibility,
69            version,
70            reducers,
71            tables,
72            subscriptions,
73            type_definitions,
74            authorities,
75            module_dependencies,
76            node_dependencies,
77        }
78    }
79
80    pub fn to_public(self) -> Self {
81        let mut type_definitions = HashMap::new();
82        let mut tables = Vec::new();
83        for table_schema in &self.tables {
84            if table_schema.visibility == TableVisibility::Public {
85                tables.push(table_schema.clone());
86                for field in &table_schema.fields {
87                    if let IntersticeType::Named(type_name) = field.field_type.clone() {
88                        if !type_definitions.contains_key(&type_name) {
89                            let type_def = self.type_definitions.get(&type_name).unwrap().clone();
90                            type_definitions.insert(type_name, type_def);
91                        }
92                    }
93                }
94                type_definitions.insert(
95                    table_schema.type_name.clone(),
96                    self.type_definitions
97                        .get(&table_schema.type_name)
98                        .unwrap()
99                        .clone(),
100                );
101            }
102        }
103        let mut reducers = Vec::new();
104        for reducer_schema in &self.reducers {
105            let mut add_reducer = true;
106            for subscription in &self.subscriptions {
107                if subscription.reducer_name == reducer_schema.name {
108                    add_reducer = false;
109                    break;
110                }
111            }
112            if add_reducer {
113                reducers.push(reducer_schema.clone());
114            }
115        }
116
117        Self {
118            abi_version: self.abi_version,
119            name: self.name,
120            visibility: self.visibility,
121            version: self.version,
122            reducers,
123            tables,
124            subscriptions: Vec::new(),
125            type_definitions,
126            authorities: self.authorities,
127            module_dependencies: self.module_dependencies,
128            node_dependencies: self.node_dependencies,
129        }
130    }
131
132    pub fn from_toml_string(toml_string: &str) -> Result<Self, toml::de::Error> {
133        toml::from_str(toml_string)
134    }
135
136    pub fn to_toml_string(&self) -> Result<String, toml::ser::Error> {
137        toml::to_string(&self)
138    }
139}