Skip to content

Add UserData Implementation Proc Macro#28

Merged
Tired-Fox merged 3 commits into
mainfrom
add-user-data-impl-proc-macro
Apr 21, 2026
Merged

Add UserData Implementation Proc Macro#28
Tired-Fox merged 3 commits into
mainfrom
add-user-data-impl-proc-macro

Conversation

@Tired-Fox
Copy link
Copy Markdown
Owner

@Tired-Fox Tired-Fox commented Apr 20, 2026

  • Update UserData proc macro to implement mlua::UserData automatically based on fields
    • Allows for skipping, readonly, writeonly, and renaming fields for lua
    • Support for tuple struct where the fields are indexed
    • Renaming can push tuple struct values into fields and named struct fields into indexes. ex: data field can be renamed to 1 to make it accessible by indexing the UserData with [1]
se mlua::{IntoLua, FromLua, Lua, StdLib};
use mlua_extras::{UserData, user_data_impl};

#[derive(Clone, UserData)]
struct Data {
    #[field(rename = 1)]
    name: String
}

#[user_data_impl]
impl Data {
    #[method]
    fn get_data(&self) -> mlua::Result<String> {
        Ok(self.name.clone())
    }

    #[metamethod(Index)]
    fn index(&self, lua: &Lua, idx: isize) -> mlua::Result<mlua::Value> {
        match idx {
            -1 => "TESTING".into_lua(lua),
            _ => Ok(mlua::Value::Nil)
        }
    }

    #[metamethod(NewIndex)]
    fn new_index(&mut self, lua: &Lua, idx: isize, value: mlua::Value) -> mlua::Result<()> {
        match idx {
            1 => self.name = String::from_lua(value, lua)?,
            _ => return Err(mlua::Error::runtime(format!("invalid index '{idx}'")))
        }
        Ok(())
    }
}

fn main() -> mlua::Result<()> {
    let lua = unsafe { Lua::unsafe_new_with(StdLib::ALL, Default::default()) };

    lua.globals().set("data", Data { name: "MluaExtras".into() })?;

    lua.load("
    print('Index [1]:', data[1])
    data[1] = 'HelloWorld'
    print('Set data[1] to \\'HelloWorld\\'')
    print('Get Data:', data:get_data())
    print('Index [-1]:', data[-1])
    ").exec()?;

    Ok(())
}

Output:

Index [1]:      MluaExtras
Set data[1] to 'HelloWorld'
Get Data:       HelloWorld
Index [-1]:     TESTING
  • Support for Enums and their variants where it fetches the value based on the current variant and sets a value based on the current variant.
    • This throws a runtime error if the user tries to access a value from the wrong variant
    • Adds a _variant field implicitly to fetch the name of the current variant.
    • Variants can be renamed for lua
use mlua_extras::{UserData, user_data_impl};

#[derive(Clone, UserData)]
enum Kind {
   A,
   B(String),
   C {
       name: String,
       age: u8,
   },
   D(u32),
}

#[user_data_impl]
impl Kind {
   #[method]
   fn message(&self) -> String {
       match self {
           Self::A => "Hello, world!".into(),
           Self::B(msg) => msg.clone(),
           Self::C{ name, age } => format!("{name} age {age}"),
           Self::D(count) => count.to_string()
       }
   }
}

fn main() -> mlua::Result<()> {
   let lua = unsafe { Lua::unsafe_new_with(StdLib::ALL, Default::default()) };

   lua.globals().set("kind", Kind::A)?;

   lua.load("
   print('Kind:', kind._variant, kind:message())
   local ok, value = pcall(function() return kind[1] end)
   print('Kind [1]: OK', ok, value)
   ").exec()?;

   Ok(())
}

Output:

Kind:   A       Hello, world!
Kind [1]: OK    false   runtime error: type variant does not contain index '1'

@Tired-Fox Tired-Fox force-pushed the add-user-data-impl-proc-macro branch 5 times, most recently from 68801e0 to 11dab80 Compare April 21, 2026 03:18
@Tired-Fox Tired-Fox force-pushed the add-user-data-impl-proc-macro branch from 11dab80 to fae7527 Compare April 21, 2026 14:59
@Tired-Fox Tired-Fox force-pushed the add-user-data-impl-proc-macro branch from 005c197 to 7a772af Compare April 21, 2026 17:34
@Tired-Fox Tired-Fox merged commit 0326e22 into main Apr 21, 2026
13 checks passed
@Tired-Fox Tired-Fox deleted the add-user-data-impl-proc-macro branch April 21, 2026 17:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant