use crate::ast::source::{ComponentDef, FnDef};
use crate::ast::utils::{NativeFnSchema, NativeNodeSchema, Type, Value};
use crate::error::Result;
use crate::library::Library;
use std::collections::HashMap;
use std::fmt;
use std::rc::Rc;
use std::sync::Arc;
#[derive(Default, Clone)]
pub struct Registry {
pub(crate) native_nodes: HashMap<String, NativeNodeSchema>,
pub(crate) components: HashMap<String, ComponentDef>,
pub(crate) native_functions: HashMap<String, NativeFnSchema>,
pub(crate) functions: HashMap<String, Rc<FnDef>>,
pub(crate) globals: HashMap<String, Value>,
pub(crate) libraries: Vec<Library>,
}
impl fmt::Debug for Registry {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Registry")
.field("native_nodes", &self.native_nodes)
.field("components", &self.components)
.field("functions", &self.functions)
.field("globals", &self.globals)
.field("native_functions", &self.native_functions.keys().collect::<Vec<_>>())
.finish()
}
}
impl Registry {
pub fn add_native_fn<F>(&mut self, name: &str, params: Vec<Type>, return_type: Type, f: F)
where
F: Fn(Vec<Value>) -> Result<Value> + Send + Sync + 'static,
{
let schema =
NativeFnSchema { name: name.to_string(), params, return_type, body: Arc::new(f) };
self.native_functions.insert(name.to_string(), schema);
}
pub fn add_node(&mut self, schema: NativeNodeSchema) {
self.native_nodes.insert(schema.type_name.to_string(), schema);
}
pub fn register_component(&mut self, def: ComponentDef) {
self.components.insert(def.name.clone(), def);
}
pub fn register_function(&mut self, def: FnDef) {
self.functions.insert(def.name.clone(), Rc::new(def));
}
pub fn add_library(&mut self, library: Library) {
let position = self.libraries.iter().position(|existing| existing.name == library.name);
match position {
Some(index) => {
self.libraries[index] = library;
}
None => {
self.libraries.push(library);
}
}
}
}