luau 0.732.0

Safe lifetime-bound Rust embedding API for the Luau runtime
use luau::{AnyUserdata, Lua};

#[derive(luau::Userdata)]
struct Counter {
    value: i32,
}

#[luau::userdata_impl]
impl Counter {
    #[luau(infallible)]
    fn new(value: Option<i32>) -> Self {
        Self {
            value: value.unwrap_or_default(),
        }
    }

    #[luau(meta, infallible)]
    fn __call(_proxy: AnyUserdata<'_>, value: Option<i32>) -> Self {
        Self::new(value)
    }

    #[luau(infallible)]
    fn increment(&mut self, step: Option<i32>) -> i32 {
        self.value += step.unwrap_or(1);
        self.value
    }
}

fn main() -> luau::Result<()> {
    let lua = Lua::new()?;

    let counter_type = lua.create_proxy::<Counter>()?;
    assert!(counter_type.is_proxy::<Counter>());
    lua.globals()?.set("Counter", counter_type)?;

    let counter: AnyUserdata<'_> = lua
        .load(
            r#"
            local counter = Counter(40)
            counter:increment()
            counter.value = counter.value + 1
            return counter
            "#,
        )
        .set_name("userdata_counter")
        .call(())?;

    counter.borrow_mut::<Counter>()?.value += 8;
    println!("{}", counter.borrow::<Counter>()?.value);
    Ok(())
}