1pub mod db;
2pub mod metrics;
3pub mod query;
4
5use icydb_schema::{
6 build::get_schema,
7 node::{Canister, Entity, Schema, Store},
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 struct ActorBuilder {
35 pub schema: Arc<Schema>,
36 pub canister: Canister,
37}
38
39impl ActorBuilder {
40 #[must_use]
42 pub const fn new(schema: Arc<Schema>, canister: Canister) -> Self {
44 Self { schema, canister }
45 }
46
47 #[must_use]
49 pub fn generate(self) -> TokenStream {
51 let mut tokens = quote!();
52
53 tokens.extend(db::generate(&self));
55 tokens.extend(metrics::generate(&self));
56 tokens.extend(query::generate(&self));
57
58 quote! {
59 #tokens
60 }
61 }
62
63 #[must_use]
65 pub fn get_stores(&self) -> Vec<(String, Store)> {
67 let canister_path = self.canister.def.path();
68
69 self.schema
70 .filter_nodes::<Store>(|node| node.canister == canister_path)
71 .map(|(path, store)| (path.to_string(), store.clone()))
72 .collect()
73 }
74
75 #[must_use]
78 pub fn get_entities(&self) -> Vec<(String, Entity)> {
80 let canister_path = self.canister.def.path();
81 let mut entities = Vec::new();
82
83 for (store_path, _) in self
84 .schema
85 .filter_nodes::<Store>(|node| node.canister == canister_path)
86 {
87 for (entity_path, entity) in self
88 .schema
89 .filter_nodes::<Entity>(|node| node.store == store_path)
90 {
91 entities.push((entity_path.to_string(), entity.clone()));
92 }
93 }
94
95 entities
96 }
97}