1mod db;
2mod macros;
3mod metrics;
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(crate) struct ActorBuilder {
35 pub(crate) schema: Arc<Schema>,
36 pub(crate) 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
57 quote! {
58 #tokens
59 }
60 }
61
62 #[must_use]
64 pub fn get_stores(&self) -> Vec<(String, Store)> {
66 let canister_path = self.canister.def.path();
67
68 self.schema
69 .filter_nodes::<Store>(|node| node.canister == canister_path)
70 .map(|(path, store)| (path.to_string(), store.clone()))
71 .collect()
72 }
73
74 #[must_use]
77 pub fn get_entities(&self) -> Vec<(String, Entity)> {
79 let canister_path = self.canister.def.path();
80 let mut entities = Vec::new();
81
82 for (store_path, _) in self
83 .schema
84 .filter_nodes::<Store>(|node| node.canister == canister_path)
85 {
86 for (entity_path, entity) in self
87 .schema
88 .filter_nodes::<Entity>(|node| node.store == store_path)
89 {
90 entities.push((entity_path.to_string(), entity.clone()));
91 }
92 }
93
94 entities
95 }
96}