Support for maps/dictionaries

This commit is contained in:
WebFreak001 2017-04-22 23:05:55 +02:00
parent 21d36af507
commit 4017e95aba
3 changed files with 54 additions and 6 deletions

View file

@ -5,6 +5,7 @@ import ddbus.util;
import std.string;
import std.typecons;
import std.range;
import std.traits;
void buildIter(TS...)(DBusMessageIter *iter, TS args) if(allCanDBus!TS) {
foreach(index, arg; args) {
@ -28,12 +29,20 @@ void buildIter(TS...)(DBusMessageIter *iter, TS args) if(allCanDBus!TS) {
buildIter(&sub, x);
}
dbus_message_iter_close_container(iter, &sub);
} else static if(isAssociativeArray!T) {
buildIter(iter, arg.byDictionaryEntries);
} else static if(isVariant!T) {
DBusMessageIter sub;
const(char)* subSig = typeSig!(VariantType!T).toStringz();
dbus_message_iter_open_container(iter, 'v', subSig, &sub);
buildIter(&sub, arg.data);
dbus_message_iter_close_container(iter, &sub);
} else static if(is(T == DictionaryEntry!(K, V), K, V)) {
DBusMessageIter sub;
dbus_message_iter_open_container(iter, 'e', null, &sub);
buildIter(&sub, arg.key);
buildIter(&sub, arg.value);
dbus_message_iter_close_container(iter, &sub);
} else static if(basicDBus!T) {
dbus_message_iter_append_basic(iter,typeCode!T,&arg);
}
@ -53,6 +62,8 @@ T readIter(T)(DBusMessageIter *iter) if (canDBus!T) {
}
static if(isTuple!T) {
assert(dbus_message_iter_get_arg_type(iter) == 'r');
} else static if(is(T == DictionaryEntry!(K1, V1), K1, V1)) {
assert(dbus_message_iter_get_arg_type(iter) == 'e');
} else {
assert(dbus_message_iter_get_arg_type(iter) == typeCode!T());
}
@ -68,6 +79,11 @@ T readIter(T)(DBusMessageIter *iter) if (canDBus!T) {
DBusMessageIter sub;
dbus_message_iter_recurse(iter, &sub);
readIterTuple!T(&sub, ret);
} else static if(is(T == DictionaryEntry!(K, V), K, V)) {
DBusMessageIter sub;
dbus_message_iter_recurse(iter, &sub);
ret.key = readIter!K(&sub);
ret.value = readIter!K(&sub);
} else static if(is(T t : U[], U)) {
assert(dbus_message_iter_get_element_type(iter) == typeCode!U);
DBusMessageIter sub;
@ -79,6 +95,13 @@ T readIter(T)(DBusMessageIter *iter) if (canDBus!T) {
DBusMessageIter sub;
dbus_message_iter_recurse(iter, &sub);
ret.data = readIter!(VariantType!T)(&sub);
} else static if(isAssociativeArray!T) {
DBusMessageIter sub;
dbus_message_iter_recurse(iter, &sub);
while(dbus_message_iter_get_arg_type(&sub) != 0) {
auto entry = readIter!(DictionaryEntry!(KeyType!T, ValueType!T))(&sub);
ret[entry.key] = entry.value;
}
} else static if(basicDBus!T) {
dbus_message_iter_get_basic(iter, &ret);
}
@ -98,9 +121,11 @@ unittest {
Variant!T var(T)(T data){ return Variant!T(data); }
Message msg = Message("org.example.wow","/wut","org.test.iface","meth");
bool[] emptyB;
auto args = tuple(5,true,"wow",var(5.9),[6,5],tuple(6.2,4,[["lol"]],emptyB,var([4,2])));
string[string] map;
map["hello"] = "world";
auto args = tuple(5,true,"wow",var(5.9),[6,5],tuple(6.2,4,[["lol"]],emptyB,var([4,2])),map);
msg.build(args.expand);
msg.signature().assertEqual("ibsvai(diaasabv)");
msg.signature().assertEqual("ibsvai(diaasabv)a{ss}");
msg.readTuple!(typeof(args))().assertEqual(args);
DBusMessageIter iter;
dbus_message_iter_init(msg.msg, &iter);
@ -110,4 +135,5 @@ unittest {
readIter!double(&iter).assertEqual(5.9);
readIter!(int[])(&iter).assertEqual([6,5]);
readIter!(Tuple!(double,int,string[][],bool[],Variant!(int[])))(&iter).assertEqual(tuple(6.2,4,[["lol"]],emptyB,var([4,2])));
readIter!(string[string])(&iter).assertEqual(["hello": "world"]);
}