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