luau 0.732.0

Safe lifetime-bound Rust embedding API for the Luau runtime
#[doc(hidden)]
#[macro_export]
macro_rules! __luau_callback_body {
    (@function $arguments:ident $body:block) => {{
        let __luau_result = (|| -> $crate::Result<_> { $body })()?;
        $arguments.finish(__luau_result)
    }};

    (@raw $arguments:ident $body:block) => {{
        let __luau_result = (|| $body)();
        $arguments.finish(__luau_result)
    }};
}

#[doc(hidden)]
#[macro_export]
macro_rules! __luau_callback_bind {
    ($arguments:ident;) => {};

    ($arguments:ident; ..$rest:ident $(,)?) => {
        let $rest: $crate::Varargs<'_> = $arguments.take_varargs();
    };

    ($arguments:ident; $argument:ident : $argument_type:ty, ..$rest:ident $(,)?) => {
        let $argument: $argument_type = $arguments.next()?;
        let $rest: $crate::Varargs<'_> = $arguments.take_varargs();
    };

    ($arguments:ident; $argument:ident : $argument_type:ty, $($remaining:tt)+) => {
        let $argument: $argument_type = $arguments.next()?;
        $crate::__luau_callback_bind!($arguments; $($remaining)+);
    };

    ($arguments:ident; $argument:ident : $argument_type:ty $(,)?) => {
        let $argument: $argument_type = $arguments.take_remaining()?;
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! __luau_callback {
    ($mode:ident move $($callback:tt)+) => {
        $crate::__luau_callback_parse!($mode [move] $($callback)+)
    };

    ($mode:ident $($callback:tt)+) => {
        $crate::__luau_callback_parse!($mode [] $($callback)+)
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! __luau_callback_parse {
    ($mode:ident $capture:tt |$lua:tt| $body:block) => {
        $crate::__luau_callback_emit_plain!($mode $capture $lua [] $body)
    };

    ($mode:ident $capture:tt |$lua:tt, ..$rest:ident $(,)?| $body:block) => {
        $crate::__luau_callback_emit_plain!($mode $capture $lua [..$rest] $body)
    };

    ($mode:ident $capture:tt |$lua:tt, $($argument:ident : $argument_type:ty,)+ ..$rest:ident $(,)?| $body:block) => {
        $crate::__luau_callback_emit_plain!(
            $mode $capture $lua [$($argument : $argument_type,)+ ..$rest] $body
        )
    };

    ($mode:ident $capture:tt |$lua:tt, $($argument:ident : $argument_type:ty),+ $(,)?| $body:block) => {
        $crate::__luau_callback_emit_plain!(
            $mode $capture $lua [$($argument : $argument_type),+] $body
        )
    };

    ($mode:ident $capture:tt |$lua:tt, $this:tt| $body:block) => {
        $crate::__luau_callback_emit_method!($mode $capture $lua $this [] $body)
    };

    ($mode:ident $capture:tt |$lua:tt, $this:tt, ..$rest:ident $(,)?| $body:block) => {
        $crate::__luau_callback_emit_method!($mode $capture $lua $this [..$rest] $body)
    };

    ($mode:ident $capture:tt |$lua:tt, $this:tt, $($argument:ident : $argument_type:ty,)+ ..$rest:ident $(,)?| $body:block) => {
        $crate::__luau_callback_emit_method!(
            $mode $capture $lua $this [$($argument : $argument_type,)+ ..$rest] $body
        )
    };

    ($mode:ident $capture:tt |$lua:tt, $this:tt, $($argument:ident : $argument_type:ty),+ $(,)?| $body:block) => {
        $crate::__luau_callback_emit_method!(
            $mode $capture $lua $this [$($argument : $argument_type),+] $body
        )
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! __luau_callback_emit_plain {
    ($mode:ident [move] $lua:tt [$($arguments:tt)*] $body:block) => {
        move |$lua, __luau_arguments: $crate::Arguments<'_>| {
            let mut __luau_arguments = __luau_arguments;
            $crate::__luau_callback_bind!(__luau_arguments; $($arguments)*);
            $crate::__luau_callback_body!(@$mode __luau_arguments $body)
        }
    };

    ($mode:ident [] $lua:tt [$($arguments:tt)*] $body:block) => {
        |$lua, __luau_arguments: $crate::Arguments<'_>| {
            let mut __luau_arguments = __luau_arguments;
            $crate::__luau_callback_bind!(__luau_arguments; $($arguments)*);
            $crate::__luau_callback_body!(@$mode __luau_arguments $body)
        }
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! __luau_callback_emit_method {
    ($mode:ident [move] $lua:tt $this:tt [$($arguments:tt)*] $body:block) => {
        move |$lua, $this, __luau_arguments: $crate::Arguments<'_>| {
            let mut __luau_arguments = __luau_arguments;
            $crate::__luau_callback_bind!(__luau_arguments; $($arguments)*);
            $crate::__luau_callback_body!(@$mode __luau_arguments $body)
        }
    };

    ($mode:ident [] $lua:tt $this:tt [$($arguments:tt)*] $body:block) => {
        |$lua, $this, __luau_arguments: $crate::Arguments<'_>| {
            let mut __luau_arguments = __luau_arguments;
            $crate::__luau_callback_bind!(__luau_arguments; $($arguments)*);
            $crate::__luau_callback_body!(@$mode __luau_arguments $body)
        }
    };
}

/// Creates a typed callback that raises a Luau error when its body returns `Err`.
///
/// Typed parameters are converted from callback arguments. An untyped
/// parameter after the [`LuaRef`](crate::LuaRef) selects the userdata-method
/// form, and `..rest` captures the remaining arguments as [`Varargs`](crate::Varargs).
///
/// ```
/// # fn main() -> luau::Result<()> {
/// let lua = luau::Lua::new()?;
/// let add = lua.create_function(
///     luau::callback!(|_lua, left: i32, right: i32| { Ok(left + right) }),
/// )?;
/// assert_eq!(add.call::<i32>((20, 22))?, 42);
/// # Ok(())
/// # }
/// ```
#[macro_export]
macro_rules! callback {
    ($($callback:tt)+) => {
        $crate::__luau_callback!(function $($callback)+)
    };
}

/// Creates a callback that converts its return value directly into Luau values.
///
/// Unlike [`callback!`], a returned `Result` is converted through
/// [`IntoLuaMulti`](crate::IntoLuaMulti) instead of raising its error. This
/// makes `Ok(value)` return `value` and `Err(error)` return `nil, error`.
#[macro_export]
macro_rules! callback_raw {
    ($($callback:tt)+) => {
        $crate::__luau_callback!(raw $($callback)+)
    };
}

/// Wraps a typed callback that raises a Luau error when its body returns `Err`.
#[macro_export]
macro_rules! function {
    ($($callback:tt)+) => {
        $crate::Function::wrap($crate::callback!($($callback)+))
    };
}

/// Wraps a mutable typed callback that raises a Luau error when its body returns `Err`.
#[macro_export]
macro_rules! function_mut {
    ($($callback:tt)+) => {
        $crate::Function::wrap_mut($crate::callback!($($callback)+))
    };
}

/// Wraps a callback whose return value is converted directly into Luau values.
#[macro_export]
macro_rules! function_raw {
    ($($callback:tt)+) => {
        $crate::Function::wrap($crate::callback_raw!($($callback)+))
    };
}

/// Wraps a mutable callback whose return value is converted directly into Luau values.
#[macro_export]
macro_rules! function_raw_mut {
    ($($callback:tt)+) => {
        $crate::Function::wrap_mut($crate::callback_raw!($($callback)+))
    };
}