@@ -175,41 +175,69 @@ function dbus.type(value)
175175 return typ
176176end
177177
178- function dbus .append_arg (iter , value , typ , subtyp )
179- for _ , v in pairs (ldbus .basic_types ) do
180- if v == typ then
181- iter :append_basic (value , typ )
182- return
183- end
178+ dbus .set_of_basic_types = {}
179+ for _ , v in pairs (ldbus .basic_types ) do
180+ dbus .set_of_basic_types [v ] = true
181+ end
182+
183+ function dbus .consume_type (dtype )
184+ if not dtype then
185+ return nil
184186 end
185- local subiter
186- if string.sub (typ , 1 , 1 ) == ldbus .types .array then
187- local subtyp = string.sub (typ , 2 )
188- subiter = iter :open_container (string.sub (typ , 1 , 1 ), subtyp )
189- if string.sub (subtyp , 1 , 1 ) ~= ' {' then
190- for _ , v in ipairs (value ) do
191- dbus .append_arg (subiter , v , subtyp )
187+ local fchar = dtype :sub (1 , 1 )
188+ if fchar == " {" then
189+ assert (dtype :sub (- 1 ) == " }" )
190+ return ldbus .types .dict_entry , dtype :sub (2 , - 2 )
191+ elseif dbus .set_of_basic_types [fchar ] or fchar == ldbus .types .array then
192+ return fchar , dtype :sub (2 )
193+ elseif fchar == ldbus .types .variant then
194+ return fchar , nil -- The type of a variant can't be detected
195+ end
196+ error (" structs unimplemented for now, type: " .. dtype , 2 )
197+ end
198+
199+ local function error_on (condition , text , lvl )
200+ if condition then
201+ error (text , lvl and lvl + 1 or 2 )
202+ end
203+ end
204+
205+ function dbus .append_arg (iter , value , dbus_type )
206+ local dt , dt_next = dbus .consume_type (dbus_type )
207+ if dbus .set_of_basic_types [dt ] then
208+ error_on (type (value ) == " table" , " expected a basic type, got a table" )
209+ iter :append_basic (value , dt )
210+ elseif dt == ldbus .types .array then
211+ error_on (type (value ) ~= " table" , " expected a table" )
212+ local arr_iter = iter :open_container (dt , dt_next )
213+ local arr_dt , arr_dt_next = dbus .consume_type (dt_next )
214+ if arr_dt == ldbus .types .dict_entry then
215+ local key_dt , value_dt = dbus .consume_type (arr_dt_next )
216+ error_on (
217+ dbus .set_of_basic_types [key_dt ] == nil ,
218+ " the key of a dict entry has to be a basic type"
219+ )
220+ for k , v in pairs (value ) do
221+ local dict_iter = arr_iter :open_container (arr_dt )
222+ dict_iter :append_basic (k , key_dt )
223+ dbus .append_arg (dict_iter , v , value_dt )
224+ arr_iter :close_container (dict_iter )
192225 end
193226 else
194- subtyp = subtyp :match (' {(%w+)}' )
195- for k , v in pairs (value ) do
196- dbus .append_arg (subiter , {k ,v }, ldbus .types .dict_entry , subtyp )
227+ for _ , v in ipairs (value ) do
228+ dbus .append_arg (arr_iter , v , dt_next )
197229 end
198230 end
199- elseif typ == ldbus .types .variant then
200- local subtyp = dbus .type (value )
201- subiter = iter :open_container (string.sub (typ , 1 , 1 ), subtyp )
202- dbus .append_arg (subiter , value , subtyp )
231+ iter :close_container (arr_iter )
232+ elseif dt == ldbus .types .variant then
233+ local val , var_dt = value , dbus .type (value )
234+ local var_iter = iter :open_container (dt , var_dt )
235+ dbus .append_arg (var_iter , val , var_dt )
236+ iter :close_container (var_iter )
203237 else
204- subiter = iter :open_container (string.sub (typ , 1 , 1 ))
205- end
206- if typ == ldbus .types .dict_entry then
207- dbus .append_arg (subiter , value [1 ], string.sub (subtyp , 1 , 1 ))
208- dbus .append_arg (subiter , value [2 ], string.sub (subtyp , 2 , 2 ))
209- elseif typ == ldbus .types .struct then
210- -- TODO
238+ error_on (dt == ldbus .types .dict_entry , " dict_entry outside of array" )
239+ error_on (dt == ldbus .types .struct , " structs are unsupported" )
211240 end
212- iter :close_container (subiter )
213241end
214242
215243function dbus .get_bus (name )
0 commit comments