[go: up one dir, main page]

codama/
codama.rs

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}