#![cfg(feature = "macros")]
use luau::{AnyUserdata, Error, FromLua, Lua, ObjectLike, Table, Userdata};
mod userdata_macro {
pub(super) mod methods;
pub(super) mod properties;
}
#[derive(Clone, Debug, Userdata, FromLua)]
struct MacroCounter {
value: i32,
#[luau(set)]
secret: String,
}
#[test]
fn derived_userdata_composes_impls_and_lending_arguments() -> Result<(), Error> {
let lua = Lua::new()?;
let proxy = lua.create_proxy::<MacroCounter>()?;
lua.globals()?.set("Counter", proxy)?;
let (counter, other): (AnyUserdata<'_>, AnyUserdata<'_>) = lua
.load(
r#"
local counter = Counter(10, "first")
local other = Counter.new(5, "second")
assert(counter.value == 10)
counter.value = 12
counter.secret = "changed"
assert(counter.secret == nil)
assert(counter.doubled == 24)
assert(Counter.KIND == "counter")
assert(Counter.metadata.category == "number")
counter.positive = 7
assert(counter.positive == 7)
local description = counter:describe("value", "raw", other, nil)
assert(description == "value:3:7:5:none", description)
return counter, other
"#,
)
.call(())?;
assert_eq!(counter.borrow::<MacroCounter>()?.value, 7);
assert_eq!(counter.borrow::<MacroCounter>()?.secret, "changed");
let cloned = lua.unpack::<MacroCounter>(luau::Value::Userdata(other.try_clone()?))?;
assert_eq!(cloned.value, 5);
let table = lua.create_table()?;
table.set("answer", 42)?;
let returned: Table<'_> = counter.call_method("identity", table)?;
assert_eq!(returned.get::<i32>("answer")?, 42);
assert_eq!(counter.call_method::<i32>("take", ())?, 7);
assert!(matches!(
counter.borrow::<MacroCounter>(),
Err(Error::UserdataDestructed)
));
Ok(())
}