1mod db;
2mod macros;
3mod metrics;
4
5use icydb_schema::{
6 build::get_schema,
7 node::{Canister, DataStore, Entity, IndexStore, Schema},
8};
9use proc_macro2::TokenStream;
10use quote::quote;
11use std::sync::Arc;
12
13#[must_use]
15pub fn generate(canister_path: &str) -> String {
17 let schema = get_schema().expect("schema must be valid before codegen");
19
20 let canister = schema.cast_node::<Canister>(canister_path).unwrap();
22
23 let code = ActorBuilder::new(Arc::new(schema.clone()), canister.clone());
25 let tokens = code.generate();
26
27 tokens.to_string()
28}
29
30pub(crate) struct ActorBuilder {
35 pub(crate) schema: Arc<Schema>,
36 pub(crate) canister: Canister,
37}
38
39impl ActorBuilder {
40 #[must_use]
41 pub const fn new(schema: Arc<Schema>, canister: Canister) -> Self {
43 Self { schema, canister }
44 }
45
46 #[must_use]
47 pub fn generate(self) -> TokenStream {
49 let mut tokens = quote!();
50
51 tokens.extend(db::generate(&self));
53 tokens.extend(metrics::generate(&self));
54
55 quote! {
56 #tokens
57 }
58 }
59
60 #[must_use]
62 pub fn get_data_stores(&self) -> Vec<(String, DataStore)> {
63 let canister_path = self.canister.def.path();
64
65 self.schema
66 .filter_nodes::<DataStore>(|node| node.canister == canister_path)
67 .map(|(path, store)| (path.to_string(), store.clone()))
68 .collect()
69 }
70
71 #[must_use]
73 pub fn get_index_stores(&self) -> Vec<(String, IndexStore)> {
74 let canister_path = self.canister.def.path();
75
76 self.schema
77 .filter_nodes::<IndexStore>(|node| node.canister == canister_path)
78 .map(|(path, store)| (path.to_string(), store.clone()))
79 .collect()
80 }
81
82 #[must_use]
84 pub fn get_entities(&self) -> Vec<(String, Entity)> {
85 let canister_path = self.canister.def.path();
86 let mut entities = Vec::new();
87
88 for (store_path, _) in self
89 .schema
90 .filter_nodes::<DataStore>(|node| node.canister == canister_path)
91 {
92 for (entity_path, entity) in self
93 .schema
94 .filter_nodes::<Entity>(|node| node.store == store_path)
95 {
96 entities.push((entity_path.to_string(), entity.clone()));
97 }
98 }
99
100 entities
101 }
102}