mlua-rs / rlua

High level Lua bindings to Rust
Other
1.72k stars 115 forks source link

[Request] UserData::from_lua #286

Closed Caellian closed 10 months ago

Caellian commented 10 months ago

Description

Provide a UserData::from_lua function that allows overriding default implementation of FromLua for types that can be constructed in several ways from either AnyUserData or some other Lua value (e.g. Table).

This can be worked around with specialization but that requires a nightly compiler.

Use Case

I have a use case with Skia where a function accepts a Paint UserData. In Skia Pain is an object that can represent anything from a discrete colore, to a texture pattern. I'd like the function to be callable with either a constructed Paint object or a table representing a color.

Example

I'd like the following piece of code:

function draw(canvas)
  paint = Gfx:newPaint()
  paint:setColor({
    r = 0.1,
    g = 0.2,
    b = 0.3,
    a = 1.0
  })
  canvas:drawCircle(20, 20, 10, paint)
end

to also work in a simpler manner where I can infer the Paint wrapper by testing for table keys:

function draw(canvas)
  canvas:drawCircle(20, 20, 10, {
    r = 0.1,
    g = 0.2,
    b = 0.3,
    a = 1.0
  })
end

Implementation

Move impl<'lua, T: 'static + UserData + Clone> FromLua<'lua> for T details into UserData::from_lua and call it from that impl instead to allow overriding default behavior. This would also allow users to call UserData::from_lua to chain the default implementation with fallback, as well as allowing customization of message in case of errors.

Caellian commented 10 months ago

Never mind, this can be achieved by adding a struct that implements FromLua and stores the value that can be constructed in several ways. Or via FromLuaMulti for several values.