1use codama_errors::{CodamaError, CodamaResult};
2use codama_korok_plugins::{resolve_plugins, DefaultPlugin, KorokPlugin};
3use codama_koroks::RootKorok;
4use codama_nodes::{HasKind, Node, NodeTrait, RootNode};
5use codama_stores::RootStore;
6use std::path::Path;
7
8pub struct Codama {
9 store: RootStore,
10 plugins: Vec<Box<dyn KorokPlugin>>,
11 with_default_plugin: bool,
12}
13
14impl Codama {
15 pub fn new(store: RootStore) -> Self {
16 Self {
17 store,
18 plugins: Vec::new(),
19 with_default_plugin: true,
20 }
21 .add_plugin(DefaultPlugin)
22 }
23
24 pub fn load<P: AsRef<Path>>(path: P) -> CodamaResult<Self> {
25 Ok(Self::new(RootStore::load(path)?))
26 }
27
28 pub fn load_all(paths: &[&Path]) -> CodamaResult<Self> {
29 Ok(Self::new(RootStore::load_all(paths)?))
30 }
31
32 pub fn hydrate(tt: proc_macro2::TokenStream) -> CodamaResult<Self> {
33 Ok(Self::new(RootStore::hydrate(tt)?))
34 }
35
36 pub fn without_default_plugin(mut self) -> Self {
37 self.with_default_plugin = false;
38 self
39 }
40
41 pub fn add_plugin<T: KorokPlugin + 'static>(mut self, plugin: T) -> Self {
42 self.plugins.push(Box::new(plugin));
43 self
44 }
45
46 pub fn get_korok(&'_ self) -> CodamaResult<RootKorok<'_>> {
47 RootKorok::parse(&self.store)
48 }
49
50 pub fn get_plugins(&self) -> &[Box<dyn KorokPlugin>] {
51 match self.with_default_plugin {
52 true => &self.plugins,
53 false => &self.plugins[1..],
54 }
55 }
56
57 pub fn get_visited_korok(&'_ self) -> CodamaResult<RootKorok<'_>> {
58 let mut korok = self.get_korok()?;
59 let run_plugins = resolve_plugins(self.get_plugins());
60 run_plugins(&mut korok)?;
61 Ok(korok)
62 }
63
64 pub fn get_node(&self) -> CodamaResult<Node> {
65 let korok = self.get_visited_korok()?;
66 korok.node.clone().ok_or(CodamaError::NodeNotFound)
67 }
68
69 pub fn get_idl(&self) -> CodamaResult<RootNode> {
70 let node = self.get_node()?;
71 match node {
72 Node::Root(root) => Ok(root),
73 _ => Err(CodamaError::UnexpectedNode {
74 expected: "RootNode".to_string(),
75 actual: node.kind().to_string(),
76 }),
77 }
78 }
79
80 pub fn get_json_idl(&self) -> CodamaResult<String> {
81 self.get_idl()?.to_json()
82 }
83}