Open terminar opened 5 years ago
get_property returns some sort of Lua'ized version of the result where some of the GVariants are translated to plain Lua.
get_property
should return plain Lua types, if it doesn't it's probably a bug. Do you have an example where the GVariant
s are not stripped?
set_property does nothing like auto conversion to GVariant.
Not entirely correct. set_property
assumes that only simple properties will be set (like a string or a number) and wraps the opts
table in a GVariant
.
Looking at your suggested code, you would like to allow the caller to pass either a GVariant
or a table that can be wrapped in a simple GVariant
(as already happens). This solution would enable passing more complex GVariant
s, but I'd like to keep that opaque to the caller, they should only be concerned with passing simple tables.
Do you have some examples where more complex properties can be set? If that's the case, we could look into adding a wrap
function in the _variant
module that does the opposite of strip
and then use it with set_property
. We should also add a comprehensive suite of test for that (similar to what's been done for strip
).
get_property
should return plain Lua types, if it doesn't it's probably a bug. Do you have an example where theGVariant
s are not stripped?
If I am stumbling upon an example, I'll give feedback - currently I can't remember where I had that problem. The main reason I mentioned it was: It returns plain Lua types (without signature-value table).
Not entirely correct.
set_property
assumes that only simple properties will be set (like a string or a number) and wraps theopts
table in aGVariant
.
Maybe I am using it completely wrong and maybe I am missing something but I just can't do:
local dev = NetworkManager(nm:GetDeviceByIpIface(devicename),"$.Device")
dev.Managed = true
dev.Autoconnect = true
(which, in my understanding, will be a real auto conversion by basic type) - it's complaining that "opts" is not a table.
I have to pass a table with "signature" and "value"
local dev = NetworkManager(nm:GetDeviceByIpIface(devicename),"$.Device")
dev.Managed = { signature = "b", value = true }
dev.Autoconnect = { signature = "b", value = true }
That's why I mentioned: set_property does no auto conversion from basic types. When I look at the code at: https://github.com/stefano-m/lua-dbus_proxy/blob/dacbc56d22436e05c5f8c60c7fa660cac78d3002/src/dbus_proxy/_proxy.lua#L259
my understanding seems to be correct. I can only pass a table with "signature" and "value" or I get an error.
A really nice version of set_property would be something like (be careful, untested copied code):
local function set_property(proxy, name, opts)
local variant_value
local vtype = type(opts)
if vtype == "boolean" then
variant_value = GVariant("b",opts)
elseif vtype == "string" then
variant_type = GVariant("s",opts)
elseif vtype == "number" then
variant_type = GVariant("u",opts)
elseif vtype == "userdata" and tostring(opts):find("GLib%.Variant$") then
variant_value = opts
elseif vtype == "table" and opts.signature and opts.value then
variant_value = GVariant(opts.signature, opts.value)
else
error("Wrong parameter, should be table with { .signature and .value } or GVariant")
end
proxy._proxy:set_cached_property(name, variant_value)
end
That would be awesome and really auto converts basic types AND gives the possibility to pass complex GVariants.
Looking at your suggested code, you would like to allow the caller to pass either a
GVariant
or a table that can be wrapped in a simpleGVariant
(as already happens). This solution would enable passing more complexGVariant
s, but I'd like to keep that opaque to the caller, they should only be concerned with passing simple tables.
One part is: it doesn't throw an error if I doesn't pass a table to the property. That took some time to understand: ok, no basic types possible (as I get them via get_property).
The other part is: when it should be opaque (and equal), let get_property also return a table with {signature = "...", value = "..."}?
Do you have some examples where more complex properties can be set? If that's the case, we could look into adding a
wrap
function in the_variant
module that does the opposite of [strip
]
I made a mistake mixing some things - The real complex types and problems I had was when I called a method on NetworkManager (GetSettings() and Update(settings)), not on properties. Using set_property I had only the mentioned problem above (need to pass a table even for basic types).
OK, I see your point more clearly now. Thanks for taking time to explain everything.
To recap:
get_property
does not return plain Lua types. If one is found, I suggest that a new issue is opened in regard.set_property
's interface is limiting and a bit awkward in that it accepts an opts
table that enables one to set only simple GVariant
properties. In this case I agree that we could introduce a breaking change to make it nicer. We can continue the discussion on this issue.So, regarding set_property
, we need a "Lua to DBus" conversion table, but I agree that we should also allow the caller to pass raw GVariant
s. The main issue I see with the conversion table is numbers, as DBus' numeric types are much richer than Lua's. Moreover Lua 5.3 can make a difference between integers and float (using math.type
) while Lua 5.2 doesn't.
Also, Lua strings could be DBus's strings, signatures or object paths. There should be some functionality in GIO
(exposed via lgi
) that could help.
And there are container types too: struct, array, dict...
So, our step zero would be to have a basic mapping by "reversing" what happens in _variant.strip
. Do you think you can do that?
References: DBus Type System:
DBus funtionality from GIO
:
I'll take a look at _variant.strip and give response here.
In _proxy.lua, the getter's and setter's are not as intuitive as they should be.
get_property returns some sort of Lua'ized version of the result where some of the GVariants are translated to plain Lua. set_property does nothing like auto conversion to GVariant.
Maybe a minimum solution would be something like:
This may report a correct error and also accepts GVariants if they are passed. It may also be nice to have a converter for the basic types (number, string) but that's just an idea.
What do you think?