Skip to content

Registration API's

This section discusses about all the registration API's in NbclEngine, what each does, and how to use it.

NbclEngine.register_node

rust
pub fn register_node(&mut self, schema: NativeNodeSchema);
NativeNodeSchema
rust
/// Defines a host-provided node
#[derive(Debug, Clone)]
pub enum PropValidation {
    /// Allow any properties
    Loose,
    /// Only allow specific keys
    Strict(HashMap<String, Type>),
}

/// Public structure used for registering custom nodes.
#[derive(Debug, Clone)]
pub struct NativeNodeSchema {
    /// Name of the Node
    pub type_name: String,
    /// Whether to enforce ID or not
    pub enforce_id: bool,
    /// Whether the property validation should be loose or strict
    pub validation: PropValidation,
    /// Children count in <(min, max)>.
    /// Use None for default functionlaity
    /// (allows any number of children).
    pub child_count: Option<(u32, u32)>,
}

Register a custom node into the engine.

Example:

rust
use crate::{NbclEngine, NativeNodeSchema};

let mut engine = NbclEngine::new();
engine.register_node(NativeNodeSchema {
    type_name: "Object".to_string(),
    enforce_id: false,
    validation: PropValidation::Loose,
    child_count: None,
});

NbclEngine.register_native_fn

rust
pub fn register_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;

Register a native function into the engine.

Example:

rust
use nbcl::{NbclEngine, Value, Type};

let mut engine = NbclEngine::new();
// 1. Name of the function
// 2. Parameters the function expects
// 3. The return type of the function
// 4. A closure that the function executes
engine.register_native_fn("example", vec![Type::Str], Type::Null, |args| {
    // arg1 is 'Type::Str'
    let arg1 = args[0];
    match arg1 {
        Value::Str(s) => {
            // do whatever
        }
        // This is unreachable because Nbcl ensures that
        // you receive the exact type you put in. 
        // However, if the type you put in were 'Type::Any',
        // then this branch does become reachable.
        _ => unreachable!()
    }

    Ok(Value::Null)
});

NbclEngine.register_library

rust
pub fn register_library(&mut self, library: Library);

Register a library into the engine.

Example:

rust
use nbcl::{NbclEngine, Value, Type};
use nbcl::library::{LibraryItem, Library};

let mut engine = NbclEngine::new();
let math = LibraryItem::define("math")
    // how you define globals
    .with_global("PI", Value::Float(std::f64::consts::PI))
    // how you define functions
    .with_fn("abs", vec![Type::Int], Type::Int, |args| {
        Ok(Value::Int(args[0].as_int().unwrap().abs()))
    });

// you can add more library items inside vec![]
let cool_lib = Library::new("coollib".into(), vec![math]);
engine.register_library(cool_lib);

// This library can be imported like this in nbcl:
// 'import coollib.math'

NbclEngine.set_global

rust
pub fn set_global(&mut self, name: &str, value: Value);

Set a global variable that can be accessed in Nbcl.

Example:

rust
use crate::{NbclEngine, Value};

let mut engine = NbclEngine::new();
engine.set_global("PI", Value::Float(std::f64::consts::PI))

NbclEngine.register_module_resolver

rust
pub fn register_module_resolver<M>(&mut self, mres: M) 
where 
    M: ModuleResolver + 'static;
ModuleResolver
rust
/// Trait for implementing custm module resolvers
pub trait ModuleResolver: Send + Sync + std::fmt::Debug {
    /// Resolves a module relative path into absolute path
    fn find_target(&self, path: &str) -> Result<PathBuf>;
}

Set a custom module resolver.

Example:

rust
use nbcl::NbclEngine;
use nbcl::module_resolver::ModuleResolver;
use std::path::PathBuf;

// Add fields if you want
#[derive(Debug, Clone)]
pub struct MyResolver;

impl ModuleResolver for MyResolver {
    fn find_target(&self, path: &str) -> Result<PathBuf> {
        // Resolve the path here and return it as a PathBuf.

        // How to report errors:
        // 
        // nbcl::error::NbclError::IO {
        //     message: "something failed".into(),
        //     hint: "try doing this...".into(),
        //     path: <pathbuf of file>
        // }
    }
}

let mut engine = NbclEngine::new();
engine.register_module_resolver(MyResolver);