lenscas / tealr

A wrapper around mlua to generate documentation, definition files and other helpers
69 stars 9 forks source link

implement TypeName for mlua::MultiValue #54

Closed coderedart closed 2 years ago

coderedart commented 2 years ago

I cannot return MultiValue from my functions because it doesn't implement it (and probably any other traits like TealData). while i can always add it to a manual impl of mlua::UserData, i cannot add documentation to those functions :(

coderedart commented 2 years ago

relevant method

methods.add_method_mut("something", |lua, ui, ()|  {
            let ctx = crate::Context::from( ui.ctx().clone());
            let data =  lua.create_userdata(ctx.clone());

            Ok((ctx, data.map(|data| Some(Value::UserData(data)))))

        });

basically, if i return Ok((T: UserData, Option<Value::UserData(AnyUserData)>)) it works. but if i use Ok((T: UserData, Result<Option<Value::UserData(AnyUserData)>>)) it doesn't work and complains about no impl of TealMultiValue.

the same method will work on mlua's UserData though. but refuses to work with TealData. is this related to this issue or should i make a new one for that?

lenscas commented 2 years ago

Not able to check right now, but i think the problem relates more about the fact that Result<> has no type name.

As you said, it works if you don't return the result but instead something else.

I'll have to see how the result gets exposed on lua's end but as teal doesn't have discriminated unions, I don't have much hope for Result to be translated to something nice.

As a temporary solution, you can use the git version of tealr. That contains a derive macro that makes it easy to expose discriminated unions in a way that teals type system understands. You could use that to make a version of result that works.

Keep in mind that generating documentation will then also require the latest git version of tealr_doc_gen

lenscas commented 2 years ago

Actually, that derive macro won't work as it also doesn't work well with generics. You can however create the same api yourself though

coderedart commented 2 years ago

I'm already using the git version of tealr due to bevy_mod_scripting dep. if i use a local copy of tealr with impl of TypeName for MultiValue, i was able to return MultiValues in TealData methods.

it doesn't fix the issue of being unable to return (T, Result) while returning (T, Option) works. but i can always just use Result::ok() for that.

lenscas commented 2 years ago

Ok, then I miss read. Mind making a pr with your TypeName implementation? Might be able to even merge it today then.

coderedart commented 2 years ago

is it okay to bump the mlua version too? I want to use the proxy_userdata thing to organize documentation hierarchy properly and allow all types to be inside on table properly.

when mlua version is set to 0.8.1, there's a lifetime error in the functions where you create TypedFunction from rust functions.

image

I had no idea what i was doing with the lifetimes :D but after messing around and just using the same 'lua lifetime for all objects and ignoring the 'callback lifetime, i was able to compile it without errors.

lenscas commented 2 years ago

Ok. I looked at it a bit better. The reason that it doesn't work is because somthing is missing a typename implementation.

Mlua's multivalue is used by mlua to return 1 or more values. You should never have to create one yourself and trying to return one will cause all typing information to be lost. Both in what the types actually are and how many values get returned.

However I made a seperate trait that is implemented by tuples where all their tyes implement typename. Using tupels that implement said trait should get you the result that you want.

Basically, mlua doesn't really care about what types get exposed to lua and gives you plenty of ways to erase said type information. Tealr on the other hand wants you to be as precise as possible as that improves documentation.