lu 0.5.1

A library for embedding Luau
Documentation
use crate::{Config, Context, FnReturn, Function, Stack, Status};

#[derive(Default)]
pub struct Library<C: Config>(Vec<(&'static str, LibraryItem<C>)>);

impl<C: Config> Library<C> {
    pub fn with(mut self, name: &'static str, item: impl Into<LibraryItem<C>>) -> Self {
        self.0.push((name, item.into()));
        self
    }

    pub fn with_constant(self, name: &'static str, constant: impl Into<LibraryConstant>) -> Self {
        self.with(name, LibraryItem::Constant(constant.into()))
    }

    pub fn with_function(self, name: &'static str, func: Function<C>) -> Self {
        self.with(name, LibraryItem::Function(func))
    }

    pub fn with_function_norm(
        self,
        name: &'static str,
        func: extern "C-unwind" fn(ctx: Context<C>) -> FnReturn,
    ) -> Self {
        self.with(name, Function::norm(name, func))
    }

    pub fn with_function_cont(
        self,
        name: &'static str,
        func: extern "C-unwind" fn(ctx: Context<C>) -> FnReturn,
        cont: extern "C-unwind" fn(ctx: Context<C>, status: Status) -> FnReturn,
    ) -> Self {
        self.with(name, Function::cont(name, func, cont))
    }

    pub fn push(&self, stack: &Stack<C>) {
        stack.reserve(2);
        stack.push_table();

        for (name, item) in &self.0 {
            stack.push_string(name);
            item.push(stack);
            stack.table_set_raw(-3);
        }
    }
}

pub enum LibraryItem<C: Config> {
    Library(Library<C>),
    Constant(LibraryConstant),
    Function(Function<C>),
}

impl<C: Config> From<Library<C>> for LibraryItem<C> {
    fn from(lib: Library<C>) -> Self {
        LibraryItem::Library(lib)
    }
}

impl<C: Config> From<LibraryConstant> for LibraryItem<C> {
    fn from(constant: LibraryConstant) -> Self {
        LibraryItem::Constant(constant)
    }
}

impl<C: Config> From<Function<C>> for LibraryItem<C> {
    fn from(func: Function<C>) -> Self {
        LibraryItem::Function(func)
    }
}

impl<C: Config> LibraryItem<C> {
    pub fn push(&self, stack: &Stack<C>) {
        match self {
            LibraryItem::Library(lib) => lib.push(stack),
            LibraryItem::Constant(constant) => constant.push(stack),
            LibraryItem::Function(func) => {
                stack.reserve(1);
                stack.push_function(func)
            }
        }
    }
}

pub enum LibraryConstant {
    Bool(bool),
    Number(f64),
    String(&'static str),
    Vector(f32, f32, f32),
}

impl LibraryConstant {
    pub fn push<C: Config>(&self, stack: &Stack<C>) {
        stack.reserve(1);

        match self {
            LibraryConstant::Bool(value) => stack.push_boolean(*value),
            LibraryConstant::Number(value) => stack.push_number(*value),
            LibraryConstant::String(value) => stack.push_string(value),
            LibraryConstant::Vector(x, y, z) => stack.push_vector((*x, *y, *z)),
        }
    }
}

impl From<bool> for LibraryConstant {
    fn from(value: bool) -> Self {
        LibraryConstant::Bool(value)
    }
}

impl From<f64> for LibraryConstant {
    fn from(value: f64) -> Self {
        LibraryConstant::Number(value)
    }
}

impl From<&'static str> for LibraryConstant {
    fn from(value: &'static str) -> Self {
        LibraryConstant::String(value)
    }
}

impl From<(f32, f32, f32)> for LibraryConstant {
    fn from(value: (f32, f32, f32)) -> Self {
        LibraryConstant::Vector(value.0, value.1, value.2)
    }
}