[go: up one dir, main page]

codama 0.6.0

Generate clients, CLIs, documentation and more from your Solana programs
Documentation
use codama_errors::{CodamaError, CodamaResult};
use codama_korok_plugins::{resolve_plugins, DefaultPlugin, KorokPlugin};
use codama_koroks::RootKorok;
use codama_nodes::{HasKind, Node, NodeTrait, RootNode};
use codama_stores::RootStore;
use std::path::Path;

pub struct Codama {
    store: RootStore,
    plugins: Vec<Box<dyn KorokPlugin>>,
    with_default_plugin: bool,
}

impl Codama {
    pub fn new(store: RootStore) -> Self {
        Self {
            store,
            plugins: Vec::new(),
            with_default_plugin: true,
        }
        .add_plugin(DefaultPlugin)
    }

    pub fn load<P: AsRef<Path>>(path: P) -> CodamaResult<Self> {
        Ok(Self::new(RootStore::load(path)?))
    }

    pub fn load_all(paths: &[&Path]) -> CodamaResult<Self> {
        Ok(Self::new(RootStore::load_all(paths)?))
    }

    pub fn hydrate(tt: proc_macro2::TokenStream) -> CodamaResult<Self> {
        Ok(Self::new(RootStore::hydrate(tt)?))
    }

    pub fn without_default_plugin(mut self) -> Self {
        self.with_default_plugin = false;
        self
    }

    pub fn add_plugin<T: KorokPlugin + 'static>(mut self, plugin: T) -> Self {
        self.plugins.push(Box::new(plugin));
        self
    }

    pub fn get_korok(&'_ self) -> CodamaResult<RootKorok<'_>> {
        RootKorok::parse(&self.store)
    }

    pub fn get_plugins(&self) -> &[Box<dyn KorokPlugin>] {
        match self.with_default_plugin {
            true => &self.plugins,
            false => &self.plugins[1..],
        }
    }

    pub fn get_visited_korok(&'_ self) -> CodamaResult<RootKorok<'_>> {
        let mut korok = self.get_korok()?;
        let run_plugins = resolve_plugins(self.get_plugins());
        run_plugins(&mut korok)?;
        Ok(korok)
    }

    pub fn get_node(&self) -> CodamaResult<Node> {
        let korok = self.get_visited_korok()?;
        korok.node.clone().ok_or(CodamaError::NodeNotFound)
    }

    pub fn get_idl(&self) -> CodamaResult<RootNode> {
        let node = self.get_node()?;
        match node {
            Node::Root(root) => Ok(root),
            _ => Err(CodamaError::UnexpectedNode {
                expected: "RootNode".to_string(),
                actual: node.kind().to_string(),
            }),
        }
    }

    pub fn get_json_idl(&self) -> CodamaResult<String> {
        self.get_idl()?.to_json()
    }
}