diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..e4d239a
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,8 @@
+[**.d]
+indent_style = space
+indent_size = 2
+
+dfmt_brace_style = otbs
+dfmt_space_after_keywords = true
+dfmt_space_after_cast = true
+dfmt_template_constraint_style = always_newline_indent
diff --git a/source/ddbus/attributes.d b/source/ddbus/attributes.d
index 1658be5..b61b2ed 100644
--- a/source/ddbus/attributes.d
+++ b/source/ddbus/attributes.d
@@ -10,17 +10,23 @@ import std.typecons : BitFlags, Flag;
Default is to include public fields only
+/
enum MarshalingFlag : ubyte {
- includePrivateFields = 1 << 0, /// Automatically include private fields
- manualOnly = 1 << 7 /// Only include fields with explicit
- /// `@Yes.DBusMarshal`. This overrides any
- /// `include` flags.
+ /++
+ Automatically include private fields
+ +/
+ includePrivateFields = 1 << 0,
+
+ /++
+ Only include fields with explicit `@Yes.DBusMarshal`. This overrides any
+ `include` flags.
+ +/
+ manualOnly = 1 << 7
}
/++
UDA for specifying DBus marshaling options on structs
+/
-auto dbusMarshaling(Args)(Args args ...)
- if (allSatisfy!(isMarshalingFlag, Args)) {
+auto dbusMarshaling(Args)(Args args...)
+ if (allSatisfy!(isMarshalingFlag, Args)) {
return BitFlags!MarshalingFlag(args);
}
@@ -29,37 +35,40 @@ package(ddbus) template isAllowedField(alias field) {
private alias getUDAs!(field, Flag!"DBusMarshal") UDAs;
static if (UDAs.length != 0) {
- static assert (UDAs.length == 1,
- "Only one UDA of type Flag!\"DBusMarshal\" allowed on struct field.");
- static assert (is(typeof(UDAs[0]) == Flag!"DBusMarshal"),
- "Did you intend to add UDA Yes.DBusMarshal or No.DBusMarshal?");
+ static assert(UDAs.length == 1,
+ "Only one UDA of type Flag!\"DBusMarshal\" allowed on struct field.");
+
+ static assert(is(typeof(UDAs[0]) == Flag!"DBusMarshal"),
+ "Did you intend to add UDA Yes.DBusMarshal or No.DBusMarshal?");
+
enum isAllowedField = cast(bool) UDAs[0];
} else static if (!(flags & MarshalingFlag.manualOnly)) {
- static if (__traits(getProtection, field) == "public")
+ static if (__traits(getProtection, field) == "public") {
enum isAllowedField = true;
- else static if (cast(bool) (flags & MarshalingFlag.includePrivateFields))
+ } else static if (cast(bool)(flags & MarshalingFlag.includePrivateFields)) {
enum isAllowedField = true;
- else
+ } else {
enum isAllowedField = false;
- } else
+ }
+ } else {
enum isAllowedField = false;
+ }
}
private template isMarshalingFlag(T) {
enum isMarshalingFlag = is(T == MarshalingFlag);
}
-private template marshalingFlags(S) if (is(S == struct)) {
+private template marshalingFlags(S)
+ if (is(S == struct)) {
private alias getUDAs!(S, BitFlags!MarshalingFlag) UDAs;
- static if (UDAs.length == 0)
+ static if (UDAs.length == 0) {
enum marshalingFlags = BitFlags!MarshalingFlag.init;
- else {
- static assert (UDAs.length == 1,
- "Only one @dbusMarshaling UDA allowed on type.");
- static assert (is(typeof(UDAs[0]) == BitFlags!MarshalingFlag),
- "Huh? Did you intend to use @dbusMarshaling UDA?");
+ } else {
+ static assert(UDAs.length == 1, "Only one @dbusMarshaling UDA allowed on type.");
+ static assert(is(typeof(UDAs[0]) == BitFlags!MarshalingFlag),
+ "Huh? Did you intend to use @dbusMarshaling UDA?");
enum marshalingFlags = UDAs[0];
}
}
-
diff --git a/source/ddbus/bus.d b/source/ddbus/bus.d
index 7712590..9d500d2 100644
--- a/source/ddbus/bus.d
+++ b/source/ddbus/bus.d
@@ -10,16 +10,18 @@ enum BusPath = "/org/freedesktop/DBus";
enum BusInterface = "org.freedesktop.DBus";
enum NameFlags {
- AllowReplace = 1, ReplaceExisting = 2, NoQueue = 4
+ AllowReplace = 1,
+ ReplaceExisting = 2,
+ NoQueue = 4
}
/// Requests a DBus well-known name.
/// returns if the name is owned after the call.
/// Involves blocking call on a DBus method, may throw an exception on failure.
bool requestName(Connection conn, string name,
- NameFlags flags = NameFlags.NoQueue | NameFlags.AllowReplace) {
- auto msg = Message(BusService,BusPath,BusInterface,"RequestName");
- msg.build(name,cast(uint)(flags));
+ NameFlags flags = NameFlags.NoQueue | NameFlags.AllowReplace) {
+ auto msg = Message(BusService, BusPath, BusInterface, "RequestName");
+ msg.build(name, cast(uint)(flags));
auto res = conn.sendWithReplyBlocking(msg).to!uint;
return (res == 1) || (res == 4);
}
@@ -28,7 +30,8 @@ bool requestName(Connection conn, string name,
/// and isn't guaranteed to work with other tasks and threads.
/// Use only for apps that only do DBus triggered things.
void simpleMainLoop(Connection conn) {
- while(dbus_connection_read_write_dispatch(conn.conn, -1)) {} // empty loop body
+ while (dbus_connection_read_write_dispatch(conn.conn, -1)) {
+ } // empty loop body
}
/// Single tick in the DBus connection which can be used for
@@ -39,7 +42,7 @@ bool tick(Connection conn) {
unittest {
import dunit.toolkit;
+
Connection conn = connectToBus();
conn.requestName("ca.thume.ddbus.testing").assertTrue();
}
-
diff --git a/source/ddbus/c_lib.d b/source/ddbus/c_lib.d
index a3ee5bf..71240bf 100644
--- a/source/ddbus/c_lib.d
+++ b/source/ddbus/c_lib.d
@@ -1,6 +1,10 @@
module ddbus.c_lib;
+
import core.stdc.config;
import core.stdc.stdarg;
+
+// dfmt off
+
extern (C):
// START dbus/dbus-arch-deps.d
alias c_long dbus_int64_t;
diff --git a/source/ddbus/conv.d b/source/ddbus/conv.d
index ebc7aa2..1fa16db 100644
--- a/source/ddbus/conv.d
+++ b/source/ddbus/conv.d
@@ -7,36 +7,37 @@ import ddbus.util;
import ddbus.thin;
import std.exception : enforce;
-import std.meta: allSatisfy;
+import std.meta : allSatisfy;
import std.string;
import std.typecons;
import std.range;
import std.traits;
import std.variant : VariantN;
-void buildIter(TS...)(DBusMessageIter *iter, TS args) if(allCanDBus!TS) {
- foreach(index, arg; args) {
+void buildIter(TS...)(DBusMessageIter* iter, TS args)
+ if (allCanDBus!TS) {
+ foreach (index, arg; args) {
alias TS[index] T;
- static if(is(T == string)) {
+ static if (is(T == string)) {
immutable(char)* cStr = arg.toStringz();
- dbus_message_iter_append_basic(iter,typeCode!T,&cStr);
- } else static if(is(T == ObjectPath)) {
+ dbus_message_iter_append_basic(iter, typeCode!T, &cStr);
+ } else static if (is(T == ObjectPath)) {
immutable(char)* cStr = arg.toString().toStringz();
- dbus_message_iter_append_basic(iter,typeCode!T,&cStr);
- } else static if(is(T==bool)) {
+ dbus_message_iter_append_basic(iter, typeCode!T, &cStr);
+ } else static if (is(T == bool)) {
dbus_bool_t longerBool = arg; // dbus bools are ints
- dbus_message_iter_append_basic(iter,typeCode!T,&longerBool);
- } else static if(isTuple!T) {
+ dbus_message_iter_append_basic(iter, typeCode!T, &longerBool);
+ } else static if (isTuple!T) {
DBusMessageIter sub;
dbus_message_iter_open_container(iter, 'r', null, &sub);
buildIter(&sub, arg.expand);
dbus_message_iter_close_container(iter, &sub);
- } else static if(isInputRange!T) {
+ } else static if (isInputRange!T) {
DBusMessageIter sub;
const(char)* subSig = (typeSig!(ElementType!T)()).toStringz();
dbus_message_iter_open_container(iter, 'a', subSig, &sub);
- foreach(x; arg) {
- static if(isInstanceOf!(DictionaryEntry, typeof(x))) {
+ foreach (x; arg) {
+ static if (isInstanceOf!(DictionaryEntry, typeof(x))) {
DBusMessageIter entry;
dbus_message_iter_open_container(&sub, 'e', null, &entry);
buildIter(&entry, x.key);
@@ -47,11 +48,11 @@ void buildIter(TS...)(DBusMessageIter *iter, TS args) if(allCanDBus!TS) {
}
}
dbus_message_iter_close_container(iter, &sub);
- } else static if(isAssociativeArray!T) {
+ } else static if (isAssociativeArray!T) {
DBusMessageIter sub;
- const(char)* subSig = typeSig!T[1..$].toStringz();
+ const(char)* subSig = typeSig!T[1 .. $].toStringz();
dbus_message_iter_open_container(iter, 'a', subSig, &sub);
- foreach(k, v; arg) {
+ foreach (k, v; arg) {
DBusMessageIter entry;
dbus_message_iter_open_container(&sub, 'e', null, &entry);
buildIter(&entry, k);
@@ -59,12 +60,11 @@ void buildIter(TS...)(DBusMessageIter *iter, TS args) if(allCanDBus!TS) {
dbus_message_iter_close_container(&sub, &entry);
}
dbus_message_iter_close_container(iter, &sub);
- } else static if(isInstanceOf!(VariantN, T)) {
- enforce(arg.hasValue,
- new InvalidValueException(arg, "dbus:" ~ cast(char) typeCode!T));
+ } else static if (isInstanceOf!(VariantN, T)) {
+ enforce(arg.hasValue, new InvalidValueException(arg, "dbus:" ~ cast(char) typeCode!T));
DBusMessageIter sub;
- foreach(AT; T.AllowedTypes) {
+ foreach (AT; T.AllowedTypes) {
if (arg.peek!AT) {
dbus_message_iter_open_container(iter, 'v', typeSig!AT.ptr, &sub);
buildIter(&sub, arg.get!AT);
@@ -72,8 +72,8 @@ void buildIter(TS...)(DBusMessageIter *iter, TS args) if(allCanDBus!TS) {
break;
}
}
- } else static if(is(T == DBusAny) || is(T == Variant!DBusAny)) {
- static if(is(T == Variant!DBusAny)) {
+ } else static if (is(T == DBusAny) || is(T == Variant!DBusAny)) {
+ static if (is(T == Variant!DBusAny)) {
auto val = arg.data;
val.explicitVariant = true;
} else {
@@ -81,66 +81,81 @@ void buildIter(TS...)(DBusMessageIter *iter, TS args) if(allCanDBus!TS) {
}
DBusMessageIter subStore;
DBusMessageIter* sub = &subStore;
- const(char)[] sig = [ cast(char) val.type ];
- if(val.type == 'a')
+ const(char)[] sig = [cast(char) val.type];
+ if (val.type == 'a') {
sig ~= val.signature;
- else if(val.type == 'r')
+ } else if (val.type == 'r') {
sig = val.signature;
+ }
+
sig ~= '\0';
- if (!val.explicitVariant)
+
+ if (!val.explicitVariant) {
sub = iter;
- else
+ } else {
dbus_message_iter_open_container(iter, 'v', sig.ptr, sub);
- if(val.type == 's') {
+ }
+
+ if (val.type == 's') {
buildIter(sub, val.str);
- } else if(val.type == 'o') {
+ } else if (val.type == 'o') {
buildIter(sub, val.obj);
- } else if(val.type == 'b') {
- buildIter(sub,val.boolean);
- } else if(dbus_type_is_basic(val.type)) {
- dbus_message_iter_append_basic(sub,val.type,&val.int64);
- } else if(val.type == 'a') {
+ } else if (val.type == 'b') {
+ buildIter(sub, val.boolean);
+ } else if (dbus_type_is_basic(val.type)) {
+ dbus_message_iter_append_basic(sub, val.type, &val.int64);
+ } else if (val.type == 'a') {
DBusMessageIter arr;
dbus_message_iter_open_container(sub, 'a', sig[1 .. $].ptr, &arr);
- if (val.signature == ['y'])
- foreach (item; val.binaryData)
+
+ if (val.signature == ['y']) {
+ foreach (item; val.binaryData) {
dbus_message_iter_append_basic(&arr, 'y', &item);
- else
- foreach(item; val.array)
+ }
+ } else {
+ foreach (item; val.array) {
buildIter(&arr, item);
+ }
+ }
+
dbus_message_iter_close_container(sub, &arr);
- } else if(val.type == 'r') {
+ } else if (val.type == 'r') {
DBusMessageIter arr;
dbus_message_iter_open_container(sub, 'r', null, &arr);
- foreach(item; val.tuple)
+
+ foreach (item; val.tuple) {
buildIter(&arr, item);
+ }
+
dbus_message_iter_close_container(sub, &arr);
- } else if(val.type == 'e') {
+ } else if (val.type == 'e') {
DBusMessageIter entry;
dbus_message_iter_open_container(sub, 'e', null, &entry);
buildIter(&entry, val.entry.key);
buildIter(&entry, val.entry.value);
dbus_message_iter_close_container(sub, &entry);
}
- if(val.explicitVariant)
+
+ if (val.explicitVariant) {
dbus_message_iter_close_container(iter, sub);
- } else static if(isInstanceOf!(Variant, T)) {
+ }
+ } else static if (isInstanceOf!(Variant, 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 == struct)) {
+ } else static if (is(T == struct)) {
DBusMessageIter sub;
dbus_message_iter_open_container(iter, 'r', null, &sub);
// Following failed because of missing 'this' for members of arg.
// That sucks. It worked without Filter.
// Reported: https://issues.dlang.org/show_bug.cgi?id=17692
-// buildIter(&sub, Filter!(isAllowedField, arg.tupleof));
+ // buildIter(&sub, Filter!(isAllowedField, arg.tupleof));
// Using foreach to work around the issue
- foreach(i, member; arg.tupleof) {
+ foreach (i, member; arg.tupleof) {
// Ugly, but we need to use tupleof again in the condition, because when
// we use `member`, isAllowedField will fail because it'll find this
// nice `buildIter` function instead of T when it looks up the parent
@@ -150,55 +165,52 @@ void buildIter(TS...)(DBusMessageIter *iter, TS args) if(allCanDBus!TS) {
}
dbus_message_iter_close_container(iter, &sub);
- } else static if(basicDBus!T) {
- dbus_message_iter_append_basic(iter,typeCode!T,&arg);
+ } else static if (basicDBus!T) {
+ dbus_message_iter_append_basic(iter, typeCode!T, &arg);
}
}
}
-T readIter(T)(DBusMessageIter *iter) if (is(T == enum)) {
+T readIter(T)(DBusMessageIter* iter)
+ if (is(T == enum)) {
import std.algorithm.searching : canFind;
alias OriginalType!T B;
B value = readIter!B(iter);
- enforce(
- only(EnumMembers!T).canFind(value),
- new InvalidValueException(value, T.stringof)
- );
+ enforce(only(EnumMembers!T).canFind(value), new InvalidValueException(value, T.stringof));
return cast(T) value;
}
-T readIter(T)(DBusMessageIter *iter) if (isInstanceOf!(BitFlags, T)) {
+T readIter(T)(DBusMessageIter* iter)
+ if (isInstanceOf!(BitFlags, T)) {
import std.algorithm.iteration : fold;
alias TemplateArgsOf!T[0] E;
alias OriginalType!E B;
- B mask = only(EnumMembers!E).fold!((a, b) => cast(B) (a | b));
+ B mask = only(EnumMembers!E).fold!((a, b) => cast(B)(a | b));
B value = readIter!B(iter);
- enforce(
- !(value & ~mask),
- new InvalidValueException(value, T.stringof)
- );
+ enforce(!(value & ~mask), new InvalidValueException(value, T.stringof));
return T(cast(E) value);
}
-T readIter(T)(DBusMessageIter *iter) if (!is(T == enum) && !isInstanceOf!(BitFlags, T) && canDBus!T) {
+T readIter(T)(DBusMessageIter* iter)
+ if (!is(T == enum) && !isInstanceOf!(BitFlags, T) && canDBus!T) {
auto argType = dbus_message_iter_get_arg_type(iter);
T ret;
- static if(!isInstanceOf!(Variant, T) || is(T == Variant!DBusAny)) {
- if(argType == 'v') {
+ static if (!isInstanceOf!(Variant, T) || is(T == Variant!DBusAny)) {
+ if (argType == 'v') {
DBusMessageIter sub;
dbus_message_iter_recurse(iter, &sub);
- static if(is(T == Variant!DBusAny)) {
+ static if (is(T == Variant!DBusAny)) {
ret = variant(readIter!DBusAny(&sub));
} else {
ret = readIter!T(&sub);
- static if(is(T == DBusAny))
+ static if (is(T == DBusAny))
ret.explicitVariant = true;
}
dbus_message_iter_next(iter);
@@ -206,36 +218,35 @@ T readIter(T)(DBusMessageIter *iter) if (!is(T == enum) && !isInstanceOf!(BitFla
}
}
- static if(
- !is(T == DBusAny)
- && !is(T == Variant!DBusAny)
- && !isInstanceOf!(VariantN, T)
- ) {
- enforce(argType == typeCode!T(),
- new TypeMismatchException(typeCode!T(), argType));
+ static if (!is(T == DBusAny) && !is(T == Variant!DBusAny) && !isInstanceOf!(VariantN, T)) {
+ enforce(argType == typeCode!T(), new TypeMismatchException(typeCode!T(), argType));
}
- static if(is(T==string) || is(T==ObjectPath)) {
+
+ static if (is(T == string) || is(T == ObjectPath)) {
const(char)* cStr;
dbus_message_iter_get_basic(iter, &cStr);
string str = cStr.fromStringz().idup; // copy string
- static if(is(T==string))
+ static if (is(T == string)) {
ret = str;
- else
+ } else {
ret = ObjectPath(str);
- } else static if(is(T==bool)) {
+ }
+ } else static if (is(T == bool)) {
dbus_bool_t longerBool;
dbus_message_iter_get_basic(iter, &longerBool);
- ret = cast(bool)longerBool;
- } else static if(isTuple!T) {
+ ret = cast(bool) longerBool;
+ } else static if (isTuple!T) {
DBusMessageIter sub;
dbus_message_iter_recurse(iter, &sub);
readIterTuple!T(&sub, ret);
- } else static if(is(T t : U[], U)) {
+ } else static if (is(T t : U[], U)) {
assert(dbus_message_iter_get_element_type(iter) == typeCode!U);
+
DBusMessageIter sub;
dbus_message_iter_recurse(iter, &sub);
- while(dbus_message_iter_get_arg_type(&sub) != 0) {
- static if(is(U == DictionaryEntry!(K,V), K, V)) {
+
+ while (dbus_message_iter_get_arg_type(&sub) != 0) {
+ static if (is(U == DictionaryEntry!(K, V), K, V)) {
DBusMessageIter entry;
dbus_message_iter_recurse(&sub, &entry);
ret ~= U(readIter!K(&entry), readIter!V(&entry));
@@ -244,17 +255,16 @@ T readIter(T)(DBusMessageIter *iter) if (!is(T == enum) && !isInstanceOf!(BitFla
ret ~= readIter!U(&sub);
}
}
- } else static if(isInstanceOf!(Variant, T)) {
+ } else static if (isInstanceOf!(Variant, T)) {
DBusMessageIter sub;
dbus_message_iter_recurse(iter, &sub);
ret.data = readIter!(VariantType!T)(&sub);
- } else static if(isInstanceOf!(VariantN, T)) {
- scope const(char)[] argSig =
- dbus_message_iter_get_signature(iter).fromStringz();
- scope(exit)
+ } else static if (isInstanceOf!(VariantN, T)) {
+ scope const(char)[] argSig = dbus_message_iter_get_signature(iter).fromStringz();
+ scope (exit)
dbus_free(cast(void*) argSig.ptr);
- foreach(AT; T.AllowedTypes) {
+ foreach (AT; T.AllowedTypes) {
// We have to compare the full signature here, not just the typecode.
// Otherwise, in case of container types, we might select the wrong one.
// We would then be calling an incorrect instance of readIter, which would
@@ -267,10 +277,11 @@ T readIter(T)(DBusMessageIter *iter) if (!is(T == enum) && !isInstanceOf!(BitFla
// If no value is in ret, apparently none of the types matched.
enforce(ret.hasValue, new TypeMismatchException(typeCode!T, argType));
- } else static if(isAssociativeArray!T) {
+ } else static if (isAssociativeArray!T) {
DBusMessageIter sub;
dbus_message_iter_recurse(iter, &sub);
- while(dbus_message_iter_get_arg_type(&sub) != 0) {
+
+ while (dbus_message_iter_get_arg_type(&sub) != 0) {
DBusMessageIter entry;
dbus_message_iter_recurse(&sub, &entry);
auto k = readIter!(KeyType!T)(&entry);
@@ -278,59 +289,64 @@ T readIter(T)(DBusMessageIter *iter) if (!is(T == enum) && !isInstanceOf!(BitFla
ret[k] = v;
dbus_message_iter_next(&sub);
}
- } else static if(is(T == DBusAny)) {
+ } else static if (is(T == DBusAny)) {
ret.type = argType;
ret.explicitVariant = false;
- if(ret.type == 's') {
+
+ if (ret.type == 's') {
ret.str = readIter!string(iter);
return ret;
- } else if(ret.type == 'o') {
+ } else if (ret.type == 'o') {
ret.obj = readIter!ObjectPath(iter);
return ret;
- } else if(ret.type == 'b') {
+ } else if (ret.type == 'b') {
ret.boolean = readIter!bool(iter);
return ret;
- } else if(dbus_type_is_basic(ret.type)) {
+ } else if (dbus_type_is_basic(ret.type)) {
dbus_message_iter_get_basic(iter, &ret.int64);
- } else if(ret.type == 'a') {
+ } else if (ret.type == 'a') {
DBusMessageIter sub;
dbus_message_iter_recurse(iter, &sub);
auto sig = dbus_message_iter_get_signature(&sub);
ret.signature = sig.fromStringz.dup;
dbus_free(sig);
- if (ret.signature == ['y'])
- while(dbus_message_iter_get_arg_type(&sub) != 0) {
+ if (ret.signature == ['y']) {
+ while (dbus_message_iter_get_arg_type(&sub) != 0) {
ubyte b;
assert(dbus_message_iter_get_arg_type(&sub) == 'y');
dbus_message_iter_get_basic(&sub, &b);
dbus_message_iter_next(&sub);
ret.binaryData ~= b;
}
- else
- while(dbus_message_iter_get_arg_type(&sub) != 0) {
+ } else {
+ while (dbus_message_iter_get_arg_type(&sub) != 0) {
ret.array ~= readIter!DBusAny(&sub);
}
- } else if(ret.type == 'r') {
+ }
+ } else if (ret.type == 'r') {
auto sig = dbus_message_iter_get_signature(iter);
ret.signature = sig.fromStringz.dup;
dbus_free(sig);
+
DBusMessageIter sub;
dbus_message_iter_recurse(iter, &sub);
- while(dbus_message_iter_get_arg_type(&sub) != 0) {
+
+ while (dbus_message_iter_get_arg_type(&sub) != 0) {
ret.tuple ~= readIter!DBusAny(&sub);
}
- } else if(ret.type == 'e') {
+ } else if (ret.type == 'e') {
DBusMessageIter sub;
dbus_message_iter_recurse(iter, &sub);
+
ret.entry = new DictionaryEntry!(DBusAny, DBusAny);
ret.entry.key = readIter!DBusAny(&sub);
ret.entry.value = readIter!DBusAny(&sub);
}
- } else static if(is(T == struct)) {
+ } else static if (is(T == struct)) {
DBusMessageIter sub;
dbus_message_iter_recurse(iter, &sub);
readIterStruct!T(&sub, ret);
- } else static if(basicDBus!T) {
+ } else static if (basicDBus!T) {
dbus_message_iter_get_basic(iter, &ret);
}
@@ -338,15 +354,16 @@ T readIter(T)(DBusMessageIter *iter) if (!is(T == enum) && !isInstanceOf!(BitFla
return ret;
}
-void readIterTuple(Tup)(DBusMessageIter *iter, ref Tup tuple) if(isTuple!Tup && allCanDBus!(Tup.Types)) {
- foreach(index, T; Tup.Types) {
+void readIterTuple(Tup)(DBusMessageIter* iter, ref Tup tuple)
+ if (isTuple!Tup && allCanDBus!(Tup.Types)) {
+ foreach (index, T; Tup.Types) {
tuple[index] = readIter!T(iter);
}
}
-void readIterStruct(S)(DBusMessageIter *iter, ref S s) if(is(S == struct) && canDBus!S)
-{
- foreach(index, T; Fields!S) {
+void readIterStruct(S)(DBusMessageIter* iter, ref S s)
+ if (is(S == struct) && canDBus!S) {
+ foreach (index, T; Fields!S) {
static if (isAllowedField!(s.tupleof[index])) {
s.tupleof[index] = readIter!T(iter);
}
@@ -356,8 +373,12 @@ void readIterStruct(S)(DBusMessageIter *iter, ref S s) if(is(S == struct) && can
unittest {
import dunit.toolkit;
import ddbus.thin;
- Variant!T var(T)(T data){ return Variant!T(data); }
- Message msg = Message("org.example.wow","/wut","org.test.iface","meth");
+
+ Variant!T var(T)(T data) {
+ return Variant!T(data);
+ }
+
+ Message msg = Message("org.example.wow", "/wut", "org.test.iface", "meth");
bool[] emptyB;
string[string] map;
map["hello"] = "world";
@@ -365,24 +386,24 @@ unittest {
anyVar.type.assertEqual('t');
anyVar.uint64.assertEqual(1561);
anyVar.explicitVariant.assertEqual(false);
- auto tupleMember = DBusAny(tuple(Variant!int(45), Variant!ushort(5), 32, [1, 2], tuple(variant(4), 5), map));
- Variant!DBusAny complexVar = variant(DBusAny([
- "hello world": variant(DBusAny(1337)),
- "array value": variant(DBusAny([42, 64])),
- "tuple value": variant(tupleMember),
- "optimized binary data": variant(DBusAny(cast(ubyte[]) [1, 2, 3, 4, 5, 6]))
- ]));
+ auto tupleMember = DBusAny(tuple(Variant!int(45), Variant!ushort(5), 32,
+ [1, 2], tuple(variant(4), 5), map));
+ Variant!DBusAny complexVar = variant(DBusAny(["hello world" : variant(DBusAny(1337)),
+ "array value" : variant(DBusAny([42, 64])), "tuple value"
+ : variant(tupleMember), "optimized binary data"
+ : variant(DBusAny(cast(ubyte[])[1, 2, 3, 4, 5, 6]))]));
complexVar.data.type.assertEqual('a');
complexVar.data.signature.assertEqual("{sv}".dup);
tupleMember.signature.assertEqual("(vviai(vi)a{ss})");
- auto args = tuple(5,true,"wow",var(5.9),[6,5],tuple(6.2,4,[["lol"]],emptyB,var([4,2])),map,anyVar,complexVar);
+ auto args = tuple(5, true, "wow", var(5.9), [6, 5], tuple(6.2, 4, [["lol"]],
+ emptyB, var([4, 2])), map, anyVar, complexVar);
msg.build(args.expand);
msg.signature().assertEqual("ibsvai(diaasabv)a{ss}tv");
msg.read!string().assertThrow!TypeMismatchException();
msg.readTuple!(Tuple!(int, bool, double)).assertThrow!TypeMismatchException();
- msg.readTuple!(Tuple!(int, bool, string, double)).assertEqual(tuple(5,true,"wow", 5.9));
+ msg.readTuple!(Tuple!(int, bool, string, double)).assertEqual(tuple(5, true, "wow", 5.9));
msg.readTuple!(typeof(args))().assertEqual(args);
DBusMessageIter iter;
@@ -391,13 +412,14 @@ unittest {
readIter!bool(&iter).assertEqual(true);
readIter!string(&iter).assertEqual("wow");
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!(int[])(&iter).assertEqual([6, 5]);
+ readIter!(Tuple!(double, int, string[][], bool[], Variant!(int[])))(&iter).assertEqual(
+ tuple(6.2, 4, [["lol"]], emptyB, var([4, 2])));
// There are two ways to read a dictionary, so duplicate the iterator to test both.
auto iter2 = iter;
- readIter!(string[string])(&iter).assertEqual(["hello": "world"]);
- auto dict = readIter!(DictionaryEntry!(string,string)[])(&iter2);
+ readIter!(string[string])(&iter).assertEqual(["hello" : "world"]);
+ auto dict = readIter!(DictionaryEntry!(string, string)[])(&iter2);
dict.length.assertEqual(1);
dict[0].key.assertEqual("hello");
dict[0].value.assertEqual("world");
@@ -412,8 +434,18 @@ unittest {
import std.variant : Algebraic;
- enum E : int { a, b, c }
- enum F : uint { x = 1, y = 2, z = 4 }
+ enum E : int {
+ a,
+ b,
+ c
+ }
+
+ enum F : uint {
+ x = 1,
+ y = 2,
+ z = 4
+ }
+
alias V = Algebraic!(byte, short, int, long, string);
Message msg = Message("org.example.wow", "/wut", "org.test.iface", "meth2");
@@ -437,4 +469,3 @@ unittest {
readIter!V(&iter).assertEqual(v1);
readIter!short(&iter).assertEqual(v2.get!short);
}
-
diff --git a/source/ddbus/exception.d b/source/ddbus/exception.d
index 1ce45e9..99713a6 100644
--- a/source/ddbus/exception.d
+++ b/source/ddbus/exception.d
@@ -2,16 +2,12 @@ module ddbus.exception;
import ddbus.c_lib;
-package T wrapErrors(T)(
- T delegate(DBusError *err) del,
- string file = __FILE__,
- size_t line = __LINE__,
- Throwable next = null
-) {
+package T wrapErrors(T)(T delegate(DBusError* err) del, string file = __FILE__,
+ size_t line = __LINE__, Throwable next = null) {
DBusError error;
dbus_error_init(&error);
T ret = del(&error);
- if(dbus_error_is_set(&error)) {
+ if (dbus_error_is_set(&error)) {
auto ex = new DBusException(&error, file, line, next);
dbus_error_free(&error);
throw ex;
@@ -23,12 +19,8 @@ package T wrapErrors(T)(
Thrown when a DBus error code was returned by libdbus.
+/
class DBusException : Exception {
- private this(
- scope DBusError *err,
- string file = __FILE__,
- size_t line = __LINE__,
- Throwable next = null
- ) pure nothrow {
+ private this(scope DBusError* err, string file = __FILE__,
+ size_t line = __LINE__, Throwable next = null) pure nothrow {
import std.string : fromStringz;
super(err.message.fromStringz().idup, file, line, next);
@@ -41,37 +33,27 @@ class DBusException : Exception {
of its actual value.
+/
class TypeMismatchException : Exception {
- package this(
- int expectedType,
- int actualType,
- string file = __FILE__,
- size_t line = __LINE__,
- Throwable next = null
- ) pure nothrow @safe {
+ package this(int expectedType, int actualType, string file = __FILE__,
+ size_t line = __LINE__, Throwable next = null) pure nothrow @safe {
string message;
+ // dfmt off
if (expectedType == 'v') {
message = "The type of value at the current position in the message is"
- ~ " incompatible to the target variant type."
- ~ " Type code of the value: '" ~ cast(char) actualType ~ '\'';
+ ~ " incompatible to the target variant type." ~ " Type code of the value: '"
+ ~ cast(char) actualType ~ '\'';
} else {
message = "The type of value at the current position in the message does"
- ~ " not match the type of value to be read."
- ~ " Expected: '" ~ cast(char) expectedType ~ "',"
- ~ " Got: '" ~ cast(char) actualType ~ '\'';
+ ~ " not match the type of value to be read." ~ " Expected: '"
+ ~ cast(char) expectedType ~ "'," ~ " Got: '" ~ cast(char) actualType ~ '\'';
}
+ // dfmt on
this(message, expectedType, actualType, file, line, next);
}
- this(
- string message,
- int expectedType,
- int actualType,
- string file = __FILE__,
- size_t line = __LINE__,
- Throwable next = null
- ) pure nothrow @safe {
+ this(string message, int expectedType, int actualType, string file = __FILE__,
+ size_t line = __LINE__, Throwable next = null) pure nothrow @safe {
_expectedType = expectedType;
_actualType = actualType;
super(message, file, line, next);
@@ -85,7 +67,7 @@ class TypeMismatchException : Exception {
return _actualType;
}
- private:
+private:
int _expectedType;
int _actualType;
}
@@ -98,19 +80,15 @@ class TypeMismatchException : Exception {
that have a constrained value set, such as Enums.
+/
class InvalidValueException : Exception {
- package this(Source)(
- Source value,
- string targetType,
- string file = __FILE__,
- size_t line = __LINE__,
- Throwable next = null
- ) {
+ package this(Source)(Source value, string targetType, string file = __FILE__,
+ size_t line = __LINE__, Throwable next = null) {
import std.conv : to;
- static if(__traits(compiles, value.to!string))
+ static if (__traits(compiles, value.to!string)) {
string valueString = value.to!string;
- else
+ } else {
string valueString = "(unprintable)";
+ }
super("Value " ~ valueString ~ " cannot be represented in type " ~ targetType);
}
diff --git a/source/ddbus/router.d b/source/ddbus/router.d
index e107963..d4017a1 100644
--- a/source/ddbus/router.d
+++ b/source/ddbus/router.d
@@ -36,19 +36,20 @@ struct MessagePattern {
hash += stringHash(&path);
hash += stringHash(&iface);
hash += stringHash(&method);
- hash += (signal?1:0);
+ hash += (signal ? 1 : 0);
return hash;
}
- bool opEquals(ref const this s) const @safe pure nothrow {
+ bool opEquals(ref const typeof(this) s) const @safe pure nothrow {
return (path == s.path) && (iface == s.iface) && (method == s.method) && (signal == s.signal);
}
}
unittest {
import dunit.toolkit;
- auto msg = Message("org.example.test", "/test","org.example.testing","testMethod");
- auto patt= new MessagePattern(msg);
+
+ auto msg = Message("org.example.test", "/test", "org.example.testing", "testMethod");
+ auto patt = new MessagePattern(msg);
patt.assertEqual(patt);
patt.signal.assertFalse();
patt.path.assertEqual("/test");
@@ -66,30 +67,34 @@ class MessageRouter {
bool handle(Message msg, Connection conn) {
MessageType type = msg.type();
- if(type != MessageType.Call && type != MessageType.Signal)
+ if (type != MessageType.Call && type != MessageType.Signal) {
return false;
+ }
+
auto pattern = MessagePattern(msg);
// import std.stdio; debug writeln("Handling ", pattern);
- if(pattern.iface == "org.freedesktop.DBus.Introspectable" &&
- pattern.method == "Introspect" && !pattern.signal) {
+ if (pattern.iface == "org.freedesktop.DBus.Introspectable"
+ && pattern.method == "Introspect" && !pattern.signal) {
handleIntrospect(pattern.path, msg, conn);
return true;
}
MessageHandler* handler = (pattern in callTable);
- if(handler is null) return false;
+ if (handler is null) {
+ return false;
+ }
// Check for matching argument types
- version(DDBusNoChecking) {
+ version (DDBusNoChecking) {
} else {
- if(!equal(join(handler.argSig), msg.signature())) {
+ if (!equal(join(handler.argSig), msg.signature())) {
return false;
}
}
- handler.func(msg,conn);
+ handler.func(msg, conn);
return true;
}
@@ -97,25 +102,39 @@ class MessageRouter {
void handlerWrapper(Message call, Connection conn) {
Tuple!Args args = call.readTuple!(Tuple!Args)();
auto retMsg = call.createReturn();
- static if(!is(Ret == void)) {
+
+ static if (!is(Ret == void)) {
Ret ret = handler(args.expand);
- static if (is(Ret == Tuple!T, T...))
+ static if (is(Ret == Tuple!T, T...)) {
retMsg.build!T(ret.expand);
- else
+ } else {
retMsg.build(ret);
+ }
} else {
handler(args.expand);
}
- if(!patt.signal)
+
+ if (!patt.signal) {
conn.send(retMsg);
+ }
}
+
static string[] args = typeSigArr!Args;
- static if(is(Ret==void)) {
+
+ static if (is(Ret == void)) {
static string[] ret = [];
} else {
static string[] ret = typeSigReturn!Ret;
}
- MessageHandler handleStruct = {func: &handlerWrapper, argSig: args, retSig: ret};
+
+ // dfmt off
+ MessageHandler handleStruct = {
+ func: &handlerWrapper,
+ argSig: args,
+ retSig: ret
+ };
+ // dfmt on
+
callTable[patt] = handleStruct;
}
@@ -123,38 +142,50 @@ class MessageRouter {
`;
string introspectXML(string path) {
- auto methods = callTable.byKey().filter!(a => (a.path == path) && !a.signal)().array()
- // .schwartzSort!((a) => a.iface, "a a.iface < b.iface)();
+ // dfmt off
+ auto methods = callTable
+ .byKey()
+ .filter!(a => (a.path == path) && !a.signal)
+ .array
+ .sort!((a, b) => a.iface < b.iface)();
+ // dfmt on
+
auto ifaces = methods.groupBy();
auto app = appender!string;
- formattedWrite(app,introspectHeader,path);
- foreach(iface; ifaces) {
- formattedWrite(app,``,iface.front.iface);
- foreach(methodPatt; iface.array()) {
- formattedWrite(app,``,methodPatt.method);
+ formattedWrite(app, introspectHeader, path);
+ foreach (iface; ifaces) {
+ formattedWrite(app, ``, iface.front.iface);
+
+ foreach (methodPatt; iface.array()) {
+ formattedWrite(app, ``, methodPatt.method);
auto handler = callTable[methodPatt];
- foreach(arg; handler.argSig) {
- formattedWrite(app,``,arg);
+
+ foreach (arg; handler.argSig) {
+ formattedWrite(app, ``, arg);
}
- foreach(arg; handler.retSig) {
- formattedWrite(app,``,arg);
+
+ foreach (arg; handler.retSig) {
+ formattedWrite(app, ``, arg);
}
+
app.put("");
}
+
app.put("");
}
string childPath = path;
- if(!childPath.endsWith("/")) {
+ if (!childPath.endsWith("/")) {
childPath ~= "/";
}
- auto children = callTable.byKey().filter!(a => (a.path.startsWith(childPath)) && !a.signal)()
- .map!((s) => s.path.chompPrefix(childPath))
- .map!((s) => s.splitter('/').front)
- .array().sort().uniq();
- foreach(child; children) {
- formattedWrite(app,``,child);
+
+ auto children = callTable.byKey()
+ .filter!(a => (a.path.startsWith(childPath)) && !a.signal)().map!(
+ (s) => s.path.chompPrefix(childPath)).map!((s) => s.splitter('/')
+ .front).array().sort().uniq();
+
+ foreach (child; children) {
+ formattedWrite(app, ``, child);
}
app.put("");
@@ -168,31 +199,33 @@ class MessageRouter {
}
}
-extern(C) private DBusHandlerResult filterFunc(DBusConnection *dConn, DBusMessage *dMsg, void *routerP) {
- MessageRouter router = cast(MessageRouter)routerP;
+extern (C) private DBusHandlerResult filterFunc(DBusConnection* dConn,
+ DBusMessage* dMsg, void* routerP) {
+ MessageRouter router = cast(MessageRouter) routerP;
dbus_message_ref(dMsg);
Message msg = Message(dMsg);
dbus_connection_ref(dConn);
Connection conn = Connection(dConn);
bool handled = router.handle(msg, conn);
- if(handled) {
+
+ if (handled) {
return DBusHandlerResult.DBUS_HANDLER_RESULT_HANDLED;
} else {
return DBusHandlerResult.DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
}
-extern(C) private void unrootUserData(void *userdata) {
+extern (C) private void unrootUserData(void* userdata) {
GC.removeRoot(userdata);
}
void registerRouter(Connection conn, MessageRouter router) {
- void *routerP = cast(void*)router;
+ void* routerP = cast(void*) router;
GC.addRoot(routerP);
dbus_connection_add_filter(conn.conn, &filterFunc, routerP, &unrootUserData);
}
-unittest{
+unittest {
import dunit.toolkit;
import std.typecons : BitFlags;
@@ -200,31 +233,53 @@ unittest{
auto router = new MessageRouter();
// set up test messages
- MessagePattern patt = MessagePattern("/root","ca.thume.test","test");
- router.setHandler!(int,int)(patt,(int p) {return 6;});
- patt = MessagePattern("/root","ca.thume.tester","lolwut");
- router.setHandler!(void,int,string)(patt,(int p, string p2) {});
- patt = MessagePattern("/root/wat","ca.thume.tester","lolwut");
- router.setHandler!(int,int)(patt,(int p) {return 6;});
- patt = MessagePattern("/root/bar","ca.thume.tester","lolwut");
- router.setHandler!(Variant!DBusAny,int)(patt,(int p) {return variant(DBusAny(p));});
- patt = MessagePattern("/root/foo","ca.thume.tester","lolwut");
- router.setHandler!(Tuple!(string,string,int),int,Variant!DBusAny)(patt,(int p, Variant!DBusAny any) {Tuple!(string,string,int) ret; ret[0] = "a"; ret[1] = "b"; ret[2] = p; return ret;});
- patt = MessagePattern("/troll","ca.thume.tester","wow");
- router.setHandler!(void)(patt,{return;});
+ MessagePattern patt = MessagePattern("/root", "ca.thume.test", "test");
+ router.setHandler!(int, int)(patt, (int p) { return 6; });
+ patt = MessagePattern("/root", "ca.thume.tester", "lolwut");
+ router.setHandler!(void, int, string)(patt, (int p, string p2) { });
+ patt = MessagePattern("/root/wat", "ca.thume.tester", "lolwut");
+ router.setHandler!(int, int)(patt, (int p) { return 6; });
+ patt = MessagePattern("/root/bar", "ca.thume.tester", "lolwut");
+ router.setHandler!(Variant!DBusAny, int)(patt, (int p) {
+ return variant(DBusAny(p));
+ });
+ patt = MessagePattern("/root/foo", "ca.thume.tester", "lolwut");
+ router.setHandler!(Tuple!(string, string, int), int,
+ Variant!DBusAny)(patt, (int p, Variant!DBusAny any) {
+ Tuple!(string, string, int) ret;
+ ret[0] = "a";
+ ret[1] = "b";
+ ret[2] = p;
+ return ret;
+ });
+ patt = MessagePattern("/troll", "ca.thume.tester", "wow");
+ router.setHandler!(void)(patt, { return; });
+
+ patt = MessagePattern("/root/fancy", "ca.thume.tester", "crazyTest");
+ enum F : ushort {
+ a = 1,
+ b = 8,
+ c = 16
+ }
+
+ struct S {
+ byte b;
+ ulong ul;
+ F f;
+ }
- patt = MessagePattern("/root/fancy","ca.thume.tester","crazyTest");
- enum F : ushort { a = 1, b = 8, c = 16 }
- struct S { byte b; ulong ul; F f; }
router.setHandler!(int)(patt, (Algebraic!(ushort, BitFlags!F, S) v) {
if (v.type is typeid(ushort) || v.type is typeid(BitFlags!F)) {
return v.coerce!int;
} else if (v.type is typeid(S)) {
auto s = v.get!S;
final switch (s.f) {
- case F.a: return s.b;
- case F.b: return cast(int) s.ul;
- case F.c: return cast(int) s.ul + s.b;
+ case F.a:
+ return s.b;
+ case F.b:
+ return cast(int) s.ul;
+ case F.c:
+ return cast(int) s.ul + s.b;
}
}
@@ -232,9 +287,9 @@ unittest{
});
static assert(!__traits(compiles, {
- patt = MessagePattern("/root/bar","ca.thume.tester","lolwut");
- router.setHandler!(void, DBusAny)(patt,(DBusAny wrongUsage){return;});
- }));
+ patt = MessagePattern("/root/bar", "ca.thume.tester", "lolwut");
+ router.setHandler!(void, DBusAny)(patt, (DBusAny wrongUsage) { return; });
+ }));
// TODO: these tests rely on nondeterministic hash map ordering
static string introspectResult = `
@@ -246,5 +301,6 @@ unittest{
static string introspectResult3 = `
`;
router.introspectXML("/root/fancy").assertEqual(introspectResult3);
- router.introspectXML("/").assertEndsWith(``);
+ router.introspectXML("/")
+ .assertEndsWith(``);
}
diff --git a/source/ddbus/simple.d b/source/ddbus/simple.d
index d58ac12..b602390 100644
--- a/source/ddbus/simple.d
+++ b/source/ddbus/simple.d
@@ -19,15 +19,16 @@ class PathIface {
this.iface = iface.toStringz();
}
- Ret call(Ret, Args...)(string meth, Args args) if(allCanDBus!Args && canDBus!Ret) {
- Message msg = Message(dbus_message_new_method_call(dest,path,iface,meth.toStringz()));
+ Ret call(Ret, Args...)(string meth, Args args)
+ if (allCanDBus!Args && canDBus!Ret) {
+ Message msg = Message(dbus_message_new_method_call(dest, path, iface, meth.toStringz()));
msg.build(args);
Message ret = conn.sendWithReplyBlocking(msg);
return ret.read!Ret();
}
Message opDispatch(string meth, Args...)(Args args) {
- Message msg = Message(dbus_message_new_method_call(dest,path,iface,meth.toStringz()));
+ Message msg = Message(dbus_message_new_method_call(dest, path, iface, meth.toStringz()));
msg.build(args);
return conn.sendWithReplyBlocking(msg);
}
@@ -40,12 +41,13 @@ class PathIface {
unittest {
import dunit.toolkit;
+
Connection conn = connectToBus();
- PathIface obj = new PathIface(conn, "org.freedesktop.DBus","/org/freedesktop/DBus",
- "org.freedesktop.DBus");
+ PathIface obj = new PathIface(conn, "org.freedesktop.DBus",
+ "/org/freedesktop/DBus", "org.freedesktop.DBus");
auto names = obj.GetNameOwner("org.freedesktop.DBus").to!string();
names.assertEqual("org.freedesktop.DBus");
- obj.call!string("GetNameOwner","org.freedesktop.DBus").assertEqual("org.freedesktop.DBus");
+ obj.call!string("GetNameOwner", "org.freedesktop.DBus").assertEqual("org.freedesktop.DBus");
}
enum SignalMethod;
@@ -63,30 +65,39 @@ enum SignalMethod;
could be instantiated with any object efficiently and placed in the router table with minimal duplication.
*/
void registerMethods(T : Object)(MessageRouter router, string path, string iface, T obj) {
- MessagePattern patt = MessagePattern(path,iface,"",false);
- foreach(member; __traits(allMembers, T)) {
+ MessagePattern patt = MessagePattern(path, iface, "", false);
+ foreach (member; __traits(allMembers, T)) {
+ // dfmt off
static if (__traits(compiles, __traits(getOverloads, obj, member))
- && __traits(getOverloads, obj, member).length > 0
- && __traits(compiles, router.setHandler(patt, &__traits(getOverloads,obj,member)[0]))) {
+ && __traits(getOverloads, obj, member).length > 0
+ && __traits(compiles, router.setHandler(patt, &__traits(getOverloads, obj, member)[0]))) {
patt.method = member;
- patt.signal = hasUDA!(__traits(getOverloads,obj,member)[0], SignalMethod);
- router.setHandler(patt, &__traits(getOverloads,obj,member)[0]);
+ patt.signal = hasUDA!(__traits(getOverloads, obj, member)[0], SignalMethod);
+ router.setHandler(patt, &__traits(getOverloads, obj, member)[0]);
}
+ // dfmt on
}
}
unittest {
import dunit.toolkit;
+
class Tester {
- int lol(int x, string s, string[string] map, Variant!DBusAny any) {return 5;}
- void wat() {}
- @SignalMethod
- void signalRecv() {}
+ int lol(int x, string s, string[string] map, Variant!DBusAny any) {
+ return 5;
+ }
+
+ void wat() {
+ }
+
+ @SignalMethod void signalRecv() {
+ }
}
+
auto o = new Tester;
auto router = new MessageRouter;
- registerMethods(router, "/","ca.thume.test",o);
- MessagePattern patt = MessagePattern("/","ca.thume.test","wat");
+ registerMethods(router, "/", "ca.thume.test", o);
+ MessagePattern patt = MessagePattern("/", "ca.thume.test", "wat");
router.callTable.assertHasKey(patt);
patt.method = "signalRecv";
patt.signal = true;
@@ -95,6 +106,6 @@ unittest {
patt.signal = false;
router.callTable.assertHasKey(patt);
auto res = router.callTable[patt];
- res.argSig.assertEqual(["i","s","a{ss}","v"]);
+ res.argSig.assertEqual(["i", "s", "a{ss}", "v"]);
res.retSig.assertEqual(["i"]);
}
diff --git a/source/ddbus/thin.d b/source/ddbus/thin.d
index 1425b18..8fd7e85 100644
--- a/source/ddbus/thin.d
+++ b/source/ddbus/thin.d
@@ -48,24 +48,28 @@ struct ObjectPath {
}
ObjectPath opBinary(string op : "~")(string rhs) const pure @safe {
- if (!rhs.startsWith("/"))
+ if (!rhs.startsWith("/")) {
return opBinary!"~"(ObjectPath("/" ~ rhs));
- else
+ } else {
return opBinary!"~"(ObjectPath(rhs));
+ }
}
ObjectPath opBinary(string op : "~")(ObjectPath rhs) const pure @safe
in {
assert(ObjectPath.isValid(_value) && ObjectPath.isValid(rhs._value));
- } out (v) {
+ }
+ out (v) {
assert(ObjectPath.isValid(v._value));
- } body {
+ }
+ body {
ObjectPath ret;
- if (_value == "/")
+ if (_value == "/") {
ret._value = rhs._value;
- else
+ } else {
ret._value = _value ~ rhs._value;
+ }
return ret;
}
@@ -85,20 +89,21 @@ struct ObjectPath {
static bool isValid(string objPath) pure @nogc nothrow @safe {
import std.ascii : isAlphaNum;
- if (!objPath.length)
+ if (!objPath.length) {
return false;
- if (objPath == "/")
+ }
+
+ if (objPath == "/") {
return true;
- if (objPath[0] != '/' || objPath[$ - 1] == '/')
+ }
+
+ if (objPath[0] != '/' || objPath[$ - 1] == '/') {
return false;
+ }
+
// .representation to avoid unicode exceptions -> @nogc & nothrow
- return objPath.representation.splitter('/').drop(1)
- .all!(a =>
- a.length &&
- a.all!(c =>
- c.isAlphaNum || c == '_'
- )
- );
+ return objPath.representation.splitter('/').drop(1).all!(a => a.length
+ && a.all!(c => c.isAlphaNum || c == '_'));
}
}
@@ -137,8 +142,7 @@ struct DBusAny {
/// Same functionality as Variant!T but with dynamic types if true.
bool explicitVariant;
- union
- {
+ union {
///
byte int8;
///
@@ -181,107 +185,125 @@ struct DBusAny {
/// Automatically creates a DBusAny object with fitting parameters from a D type or Variant!T.
/// Pass a `Variant!T` to make this an explicit variant.
this(T)(T value) {
- static if(is(T == byte) || is(T == ubyte)) {
+ static if (is(T == byte) || is(T == ubyte)) {
this(typeCode!byte, null, false);
int8 = cast(byte) value;
- } else static if(is(T == short)) {
+ } else static if (is(T == short)) {
this(typeCode!short, null, false);
int16 = cast(short) value;
- } else static if(is(T == ushort)) {
+ } else static if (is(T == ushort)) {
this(typeCode!ushort, null, false);
uint16 = cast(ushort) value;
- } else static if(is(T == int)) {
+ } else static if (is(T == int)) {
this(typeCode!int, null, false);
int32 = cast(int) value;
- } else static if(is(T == uint)) {
+ } else static if (is(T == uint)) {
this(typeCode!uint, null, false);
uint32 = cast(uint) value;
- } else static if(is(T == long)) {
+ } else static if (is(T == long)) {
this(typeCode!long, null, false);
int64 = cast(long) value;
- } else static if(is(T == ulong)) {
+ } else static if (is(T == ulong)) {
this(typeCode!ulong, null, false);
uint64 = cast(ulong) value;
- } else static if(is(T == double)) {
+ } else static if (is(T == double)) {
this(typeCode!double, null, false);
float64 = cast(double) value;
- } else static if(isSomeString!T) {
+ } else static if (isSomeString!T) {
this(typeCode!string, null, false);
str = value.to!string;
- } else static if(is(T == bool)) {
+ } else static if (is(T == bool)) {
this(typeCode!bool, null, false);
boolean = cast(bool) value;
- } else static if(is(T == ObjectPath)) {
+ } else static if (is(T == ObjectPath)) {
this(typeCode!ObjectPath, null, false);
obj = value;
- } else static if(is(T == Variant!R, R)) {
- static if(is(R == DBusAny)) {
+ } else static if (is(T == Variant!R, R)) {
+ static if (is(R == DBusAny)) {
type = value.data.type;
signature = value.data.signature;
explicitVariant = true;
- if(type == 'a' || type == 'r') {
- if(signature == ['y'])
+ if (type == 'a' || type == 'r') {
+ if (signature == ['y']) {
binaryData = value.data.binaryData;
- else
+ } else {
array = value.data.array;
- } else if(type == 's')
+ }
+ } else if (type == 's') {
str = value.data.str;
- else if(type == 'e')
+ } else if (type == 'e') {
entry = value.data.entry;
- else
+ } else {
uint64 = value.data.uint64;
+ }
} else {
this(value.data);
explicitVariant = true;
}
- } else static if(is(T : DictionaryEntry!(K, V), K, V)) {
+ } else static if (is(T : DictionaryEntry!(K, V), K, V)) {
this('e', null, false);
entry = new DictionaryEntry!(DBusAny, DBusAny)();
- static if(is(K == DBusAny))
+ static if (is(K == DBusAny)) {
entry.key = value.key;
- else
+ } else {
entry.key = DBusAny(value.key);
- static if(is(V == DBusAny))
+ }
+ static if (is(V == DBusAny)) {
entry.value = value.value;
- else
+ } else {
entry.value = DBusAny(value.value);
- } else static if(is(T == ubyte[]) || is(T == byte[])) {
+ }
+ } else static if (is(T == ubyte[]) || is(T == byte[])) {
this('a', ['y'], false);
binaryData = cast(ubyte[]) value;
- } else static if(isInputRange!T) {
+ } else static if (isInputRange!T) {
this.type = 'a';
- static assert(!is(ElementType!T == DBusAny), "Array must consist of the same type, use Variant!DBusAny or DBusAny(tuple(...)) instead");
+
+ static assert(!is(ElementType!T == DBusAny),
+ "Array must consist of the same type, use Variant!DBusAny or DBusAny(tuple(...)) instead");
+
static assert(.typeSig!(ElementType!T) != "y");
+
this.signature = .typeSig!(ElementType!T);
this.explicitVariant = false;
- foreach(elem; value)
+
+ foreach (elem; value) {
array ~= DBusAny(elem);
- } else static if(isTuple!T) {
+ }
+ } else static if (isTuple!T) {
this.type = 'r';
this.signature = ['('];
this.explicitVariant = false;
- foreach(index, R; value.Types) {
+
+ foreach (index, R; value.Types) {
auto var = DBusAny(value[index]);
tuple ~= var;
- if(var.explicitVariant)
+
+ if (var.explicitVariant) {
this.signature ~= 'v';
- else {
- if (var.type != 'r')
+ } else {
+ if (var.type != 'r') {
this.signature ~= cast(char) var.type;
- if(var.type == 'a' || var.type == 'r')
+ }
+
+ if (var.type == 'a' || var.type == 'r') {
this.signature ~= var.signature;
+ }
}
}
+
this.signature ~= ')';
- } else static if(isAssociativeArray!T) {
+ } else static if (isAssociativeArray!T) {
this(value.byDictionaryEntries);
- } else static assert(false, T.stringof ~ " not convertible to a Variant");
+ } else {
+ static assert(false, T.stringof ~ " not convertible to a Variant");
+ }
}
///
string toString() const {
string valueStr;
- switch(type) {
+ switch (type) {
case typeCode!byte:
valueStr = int8.to!string;
break;
@@ -318,10 +340,12 @@ struct DBusAny {
case 'a':
import std.digest.digest : toHexString;
- if(signature == ['y'])
+ if (signature == ['y']) {
valueStr = "binary(" ~ binaryData.toHexString ~ ')';
- else
+ } else {
valueStr = '[' ~ array.map!(a => a.toString).join(", ") ~ ']';
+ }
+
break;
case 'r':
valueStr = '(' ~ tuple.map!(a => a.toString).join(", ") ~ ')';
@@ -333,10 +357,9 @@ struct DBusAny {
valueStr = "unknown";
break;
}
- return "DBusAny(" ~ cast(char) type
- ~ ", \"" ~ signature.idup
- ~ "\", " ~ (explicitVariant ? "explicit" : "implicit")
- ~ ", " ~ valueStr ~ ")";
+
+ return "DBusAny(" ~ cast(char) type ~ ", \"" ~ signature.idup ~ "\", " ~ (explicitVariant
+ ? "explicit" : "implicit") ~ ", " ~ valueStr ~ ")";
}
/++
@@ -354,24 +377,21 @@ struct DBusAny {
DBusAny object is not the same as the DBus type used to represent T.
+/
T get(T)() @property const
- if(staticIndexOf!(T, BasicTypes) >= 0)
- {
- enforce(type == typeCode!T,
- new TypeMismatchException(
- "Cannot get a " ~ T.stringof ~ " from a DBusAny with"
- ~ " a value of DBus type '" ~ typeSig ~ "'.", typeCode!T, type));
+ if (staticIndexOf!(T, BasicTypes) >= 0) {
+ enforce(type == typeCode!T, new TypeMismatchException(
+ "Cannot get a " ~ T.stringof ~ " from a DBusAny with" ~ " a value of DBus type '" ~ typeSig ~ "'.",
+ typeCode!T, type));
- static if(isIntegral!T) {
- enum memberName =
- (isUnsigned!T ? "uint" : "int") ~ (T.sizeof * 8).to!string;
+ static if (isIntegral!T) {
+ enum memberName = (isUnsigned!T ? "uint" : "int") ~ (T.sizeof * 8).to!string;
return __traits(getMember, this, memberName);
- } else static if(is(T == double)) {
+ } else static if (is(T == double)) {
return float64;
- } else static if(is(T == string)) {
+ } else static if (is(T == string)) {
return str;
- } else static if(is(T == ObjectPath)) {
+ } else static if (is(T == ObjectPath)) {
return obj;
- } else static if(is(T == bool)) {
+ } else static if (is(T == bool)) {
return boolean;
} else {
static assert(false);
@@ -380,12 +400,9 @@ struct DBusAny {
/// ditto
T get(T)() @property const
- if(is(T == const(DBusAny)[]))
- {
- enforce((type == 'a' && signature != "y") || type == 'r',
- new TypeMismatchException(
- "Cannot get a " ~ T.stringof ~ " from a DBusAny with"
- ~ " a value of DBus type '" ~ this.typeSig ~ "'.",
+ if (is(T == const(DBusAny)[])) {
+ enforce((type == 'a' && signature != "y") || type == 'r', new TypeMismatchException(
+ "Cannot get a " ~ T.stringof ~ " from a DBusAny with" ~ " a value of DBus type '" ~ this.typeSig ~ "'.",
typeCode!T, type));
return array;
@@ -393,12 +410,9 @@ struct DBusAny {
/// ditto
T get(T)() @property const
- if (is(T == const(ubyte)[]))
- {
- enforce(type == 'a' && signature == "y",
- new TypeMismatchException(
- "Cannot get a " ~ T.stringof ~ " from a DBusAny with"
- ~ " a value of DBus type '" ~ this.typeSig ~ "'.",
+ if (is(T == const(ubyte)[])) {
+ enforce(type == 'a' && signature == "y", new TypeMismatchException(
+ "Cannot get a " ~ T.stringof ~ " from a DBusAny with" ~ " a value of DBus type '" ~ this.typeSig ~ "'.",
typeCode!T, type));
return binaryData;
@@ -408,10 +422,12 @@ struct DBusAny {
DBusAny[DBusAny] toAA() {
enforce(type == 'a' && signature && signature[0] == '{');
DBusAny[DBusAny] aa;
- foreach(val; array) {
+
+ foreach (val; array) {
enforce(val.type == 'e');
aa[val.entry.key] = val.entry.value;
}
+
return aa;
}
@@ -421,34 +437,34 @@ struct DBusAny {
Returns:
The type signature of the value stored in this DBusAny object.
+/
- string typeSig() @property const pure nothrow @safe
- {
- if(type == 'a') {
+ string typeSig() @property const pure nothrow @safe {
+ if (type == 'a') {
return "a" ~ signature;
- } else if(type == 'r') {
+ } else if (type == 'r') {
return signature;
- } else if(type == 'e') {
- return () @trusted {
+ } else if (type == 'e') {
+ return () @trusted{
return "{" ~ entry.key.signature ~ entry.value.signature ~ "}";
- } ();
+ }();
} else {
- return [ cast(char) type ];
+ return [cast(char) type];
}
}
/// Converts a basic type, a tuple or an array to the D type with type checking. Tuples can get converted to an array too.
T to(T)() {
- static if(is(T == Variant!R, R)) {
- static if(is(R == DBusAny)) {
+ static if (is(T == Variant!R, R)) {
+ static if (is(R == DBusAny)) {
auto v = to!R;
v.explicitVariant = false;
return Variant!R(v);
- } else
+ } else {
return Variant!R(to!R);
- } else static if(is(T == DBusAny)) {
+ }
+ } else static if (is(T == DBusAny)) {
return this;
- } else static if(isIntegral!T || isFloatingPoint!T) {
- switch(type) {
+ } else static if (isIntegral!T || isFloatingPoint!T) {
+ switch (type) {
case typeCode!byte:
return cast(T) int8;
case typeCode!short:
@@ -468,79 +484,106 @@ struct DBusAny {
default:
throw new Exception("Can't convert type " ~ cast(char) type ~ " to " ~ T.stringof);
}
- } else static if(is(T == bool)) {
- if(type == 'b')
+ } else static if (is(T == bool)) {
+ if (type == 'b') {
return boolean;
- else
+ } else {
throw new Exception("Can't convert type " ~ cast(char) type ~ " to " ~ T.stringof);
- } else static if(isSomeString!T) {
- if(type == 's')
+ }
+ } else static if (isSomeString!T) {
+ if (type == 's') {
return str.to!T;
- else if(type == 'o')
+ } else if (type == 'o') {
return obj.toString();
- else
+ } else {
throw new Exception("Can't convert type " ~ cast(char) type ~ " to " ~ T.stringof);
- } else static if(is(T == ObjectPath)) {
- if(type == 'o')
+ }
+ } else static if (is(T == ObjectPath)) {
+ if (type == 'o') {
return obj;
- else
+ } else {
throw new Exception("Can't convert type " ~ cast(char) type ~ " to " ~ T.stringof);
- } else static if(isDynamicArray!T) {
- if(type != 'a' && type != 'r')
+ }
+ } else static if (isDynamicArray!T) {
+ if (type != 'a' && type != 'r') {
throw new Exception("Can't convert type " ~ cast(char) type ~ " to an array");
+ }
+
T ret;
- if(signature == ['y']) {
- static if(isIntegral!(ElementType!T))
- foreach(elem; binaryData)
+ if (signature == ['y']) {
+ static if (isIntegral!(ElementType!T)) {
+ foreach (elem; binaryData) {
ret ~= elem.to!(ElementType!T);
- } else
- foreach(elem; array)
+ }
+ }
+ } else {
+ foreach (elem; array) {
ret ~= elem.to!(ElementType!T);
+ }
+ }
+
return ret;
- } else static if(isTuple!T) {
- if(type != 'r')
+ } else static if (isTuple!T) {
+ if (type != 'r') {
throw new Exception("Can't convert type " ~ cast(char) type ~ " to " ~ T.stringof);
+ }
+
T ret;
enforce(ret.Types.length == tuple.length, "Tuple length mismatch");
- foreach(index, T; ret.Types)
+ foreach (index, T; ret.Types) {
ret[index] = tuple[index].to!T;
+ }
+
return ret;
- } else static if(isAssociativeArray!T) {
- if(type != 'a' || !signature || signature[0] != '{')
+ } else static if (isAssociativeArray!T) {
+ if (type != 'a' || !signature || signature[0] != '{') {
throw new Exception("Can't convert type " ~ cast(char) type ~ " to " ~ T.stringof);
+ }
+
T ret;
- foreach(pair; array) {
+ foreach (pair; array) {
enforce(pair.type == 'e');
ret[pair.entry.key.to!(KeyType!T)] = pair.entry.value.to!(ValueType!T);
}
+
return ret;
- } else static assert(false, "Can't convert variant to " ~ T.stringof);
+ } else {
+ static assert(false, "Can't convert variant to " ~ T.stringof);
+ }
}
bool opEquals(ref in DBusAny b) const {
- if(b.type != type || b.explicitVariant != explicitVariant)
+ if (b.type != type || b.explicitVariant != explicitVariant) {
return false;
- if((type == 'a' || type == 'r') && b.signature != signature)
+ }
+
+ if ((type == 'a' || type == 'r') && b.signature != signature) {
return false;
- if(type == 'a' && signature == ['y'])
+ }
+
+ if (type == 'a' && signature == ['y']) {
return binaryData == b.binaryData;
- if(type == 'a')
+ }
+
+ if (type == 'a') {
return array == b.array;
- else if(type == 'r')
+ } else if (type == 'r') {
return tuple == b.tuple;
- else if(type == 's')
+ } else if (type == 's') {
return str == b.str;
- else if(type == 'o')
+ } else if (type == 'o') {
return obj == b.obj;
- else if(type == 'e')
+ } else if (type == 'e') {
return entry == b.entry || (entry && b.entry && *entry == *b.entry);
- else
+ } else {
return uint64 == b.uint64;
+ }
}
}
unittest {
import dunit.toolkit;
+
DBusAny set(string member, T)(DBusAny v, T value) {
mixin("v." ~ member ~ " = value;");
return v;
@@ -549,12 +592,14 @@ unittest {
void test(T)(T value, DBusAny b) {
assertEqual(DBusAny(value), b);
- static if(is(T == Variant!R, R)) {
- static if(__traits(compiles, b.get!R))
+ static if (is(T == Variant!R, R)) {
+ static if (__traits(compiles, b.get!R)) {
assertEqual(b.get!R, value.data);
+ }
} else {
- static if(__traits(compiles, b.get!T))
+ static if (__traits(compiles, b.get!T)) {
assertEqual(b.get!T, value);
+ }
}
assertEqual(b.to!T, value);
@@ -569,7 +614,8 @@ unittest {
test(cast(long) 184, set!"int64"(DBusAny('x', null, false), cast(long) 184));
test(cast(ulong) 184, set!"uint64"(DBusAny('t', null, false), cast(ulong) 184));
test(true, set!"boolean"(DBusAny('b', null, false), true));
- test(cast(ubyte[]) [1, 2, 3], set!"binaryData"(DBusAny('a', ['y'], false), cast(ubyte[]) [1, 2, 3]));
+ test(cast(ubyte[])[1, 2, 3], set!"binaryData"(DBusAny('a', ['y'], false),
+ cast(ubyte[])[1, 2, 3]));
test(variant(cast(ubyte) 184), set!"int8"(DBusAny('y', null, true), cast(byte) 184));
test(variant(cast(short) 184), set!"int16"(DBusAny('n', null, true), cast(short) 184));
@@ -579,18 +625,24 @@ unittest {
test(variant(cast(long) 184), set!"int64"(DBusAny('x', null, true), cast(long) 184));
test(variant(cast(ulong) 184), set!"uint64"(DBusAny('t', null, true), cast(ulong) 184));
test(variant(true), set!"boolean"(DBusAny('b', null, true), true));
- test(variant(cast(ubyte[]) [1, 2, 3]), set!"binaryData"(DBusAny('a', ['y'], true), cast(ubyte[]) [1, 2, 3]));
+ test(variant(cast(ubyte[])[1, 2, 3]), set!"binaryData"(DBusAny('a', ['y'],
+ true), cast(ubyte[])[1, 2, 3]));
test(variant(DBusAny(5)), set!"int32"(DBusAny('i', null, true), 5));
test([1, 2, 3], set!"array"(DBusAny('a', ['i'], false), [DBusAny(1), DBusAny(2), DBusAny(3)]));
- test(variant([1, 2, 3]), set!"array"(DBusAny('a', ['i'], true), [DBusAny(1), DBusAny(2), DBusAny(3)]));
+ test(variant([1, 2, 3]), set!"array"(DBusAny('a', ['i'], true), [DBusAny(1),
+ DBusAny(2), DBusAny(3)]));
- test(tuple("a", 4, [1, 2]), set!"tuple"(DBusAny('r', "(siai)".dup, false), [DBusAny("a"), DBusAny(4), DBusAny([1, 2])]));
- test(tuple("a", variant(4), variant([1, 2])), set!"tuple"(DBusAny('r', "(svv)", false), [DBusAny("a"), DBusAny(variant(4)), DBusAny(variant([1, 2]))]));
+ test(tuple("a", 4, [1, 2]), set!"tuple"(DBusAny('r', "(siai)".dup, false),
+ [DBusAny("a"), DBusAny(4), DBusAny([1, 2])]));
+ test(tuple("a", variant(4), variant([1, 2])), set!"tuple"(DBusAny('r',
+ "(svv)", false), [DBusAny("a"), DBusAny(variant(4)), DBusAny(variant([1, 2]))]));
- test(["a": "b"], set!"array"(DBusAny('a', "{ss}", false), [DBusAny(DictionaryEntry!(DBusAny, DBusAny)(DBusAny("a"), DBusAny("b")))]));
- test([variant("a"): 4], set!"array"(DBusAny('a', "{vi}", false), [DBusAny(DictionaryEntry!(DBusAny, DBusAny)(DBusAny(variant("a")), DBusAny(4)))]));
+ test(["a" : "b"], set!"array"(DBusAny('a', "{ss}", false),
+ [DBusAny(DictionaryEntry!(DBusAny, DBusAny)(DBusAny("a"), DBusAny("b")))]));
+ test([variant("a") : 4], set!"array"(DBusAny('a', "{vi}", false),
+ [DBusAny(DictionaryEntry!(DBusAny, DBusAny)(DBusAny(variant("a")), DBusAny(4)))]));
}
/// Marks the data as variant on serialization
@@ -605,17 +657,21 @@ Variant!T variant(T)(T data) {
enum MessageType {
Invalid = 0,
- Call, Return, Error, Signal
+ Call,
+ Return,
+ Error,
+ Signal
}
struct Message {
- DBusMessage *msg;
+ DBusMessage* msg;
this(string dest, string path, string iface, string method) {
- msg = dbus_message_new_method_call(dest.toStringz(), path.toStringz(), iface.toStringz(), method.toStringz());
+ msg = dbus_message_new_method_call(dest.toStringz(), path.toStringz(),
+ iface.toStringz(), method.toStringz());
}
- this(DBusMessage *m) {
+ this(DBusMessage* m) {
msg = m;
}
@@ -627,7 +683,8 @@ struct Message {
dbus_message_unref(msg);
}
- void build(TS...)(TS args) if(allCanDBus!TS) {
+ void build(TS...)(TS args)
+ if (allCanDBus!TS) {
DBusMessageIter iter;
dbus_message_iter_init_append(msg, &iter);
buildIter(&iter, args);
@@ -639,14 +696,17 @@ struct Message {
read the first argument. This is suitable for single item returns.
To read multiple arguments use readTuple.
*/
- T read(T)() if(canDBus!T) {
+ T read(T)()
+ if (canDBus!T) {
DBusMessageIter iter;
dbus_message_iter_init(msg, &iter);
return readIter!T(&iter);
}
+
alias read to;
- Tup readTuple(Tup)() if(isTuple!Tup && allCanDBus!(Tup.Types)) {
+ Tup readTuple(Tup)()
+ if (isTuple!Tup && allCanDBus!(Tup.Types)) {
DBusMessageIter iter;
dbus_message_iter_init(msg, &iter);
Tup ret;
@@ -659,7 +719,7 @@ struct Message {
}
MessageType type() {
- return cast(MessageType)dbus_message_get_type(msg);
+ return cast(MessageType) dbus_message_get_type(msg);
}
bool isCall() {
@@ -673,21 +733,25 @@ struct Message {
assert(cStr != null);
return cStr.fromStringz().idup;
}
+
string path() {
const(char)* cStr = dbus_message_get_path(msg);
assert(cStr != null);
return cStr.fromStringz().idup;
}
+
string iface() {
const(char)* cStr = dbus_message_get_interface(msg);
assert(cStr != null);
return cStr.fromStringz().idup;
}
+
string member() {
const(char)* cStr = dbus_message_get_member(msg);
assert(cStr != null);
return cStr.fromStringz().idup;
}
+
string sender() {
const(char)* cStr = dbus_message_get_sender(msg);
assert(cStr != null);
@@ -697,13 +761,14 @@ struct Message {
unittest {
import dunit.toolkit;
- auto msg = Message("org.example.test", "/test","org.example.testing","testMethod");
+
+ auto msg = Message("org.example.test", "/test", "org.example.testing", "testMethod");
msg.path().assertEqual("/test");
}
struct Connection {
- DBusConnection *conn;
- this(DBusConnection *connection) {
+ DBusConnection* conn;
+ this(DBusConnection* connection) {
conn = connection;
}
@@ -720,7 +785,7 @@ struct Connection {
}
void send(Message msg) {
- dbus_connection_send(conn,msg.msg, null);
+ dbus_connection_send(conn, msg.msg, null);
}
void sendBlocking(Message msg) {
@@ -729,13 +794,13 @@ struct Connection {
}
Message sendWithReplyBlocking(Message msg, int timeout = -1) {
- DBusMessage *dbusMsg = msg.msg;
+ DBusMessage* dbusMsg = msg.msg;
dbus_message_ref(dbusMsg);
- DBusMessage *reply = wrapErrors((err) {
- auto ret = dbus_connection_send_with_reply_and_block(conn,dbusMsg,timeout,err);
- dbus_message_unref(dbusMsg);
- return ret;
- });
+ DBusMessage* reply = wrapErrors((err) {
+ auto ret = dbus_connection_send_with_reply_and_block(conn, dbusMsg, timeout, err);
+ dbus_message_unref(dbusMsg);
+ return ret;
+ });
return Message(reply);
}
@@ -758,7 +823,7 @@ unittest {
struct S2 {
int h, i;
@(Yes.DBusMarshal) int j, k;
- int *p;
+ int* p;
}
@dbusMarshaling(MarshalingFlag.includePrivateFields)
@@ -774,40 +839,32 @@ unittest {
__gshared int dummy;
- enum testStruct = S3(
- variant(5), "blah",
- S1(-7, 63.5, "test"),
- S2(84, -123, 78, 432, &dummy),
- 16
- );
+ enum testStruct = S3(variant(5), "blah", S1(-7, 63.5, "test"), S2(84, -123,
+ 78, 432, &dummy), 16);
msg.build(testStruct);
// Non-marshaled fields should appear as freshly initialized
- enum expectedResult = S3(
- variant(5), "blah",
- S1(int.init, 63.5, "test"),
- S2(int.init, int.init, 78, 432, null),
- uint.init
- );
+ enum expectedResult = S3(variant(5), "blah", S1(int.init, 63.5, "test"),
+ S2(int.init, int.init, 78, 432, null), uint.init);
msg.read!S3().assertEqual(expectedResult);
-
}
Connection connectToBus(DBusBusType bus = DBusBusType.DBUS_BUS_SESSION) {
- DBusConnection *conn = wrapErrors((err) { return dbus_bus_get(bus,err); });
+ DBusConnection* conn = wrapErrors((err) { return dbus_bus_get(bus, err); });
return Connection(conn);
}
unittest {
import dunit.toolkit;
+
// This test will only pass if DBus is installed.
Connection conn = connectToBus();
conn.conn.assertTruthy();
// We can only count on no system bus on OSX
- version(OSX) {
+ version (OSX) {
connectToBus(DBusBusType.DBUS_BUS_SYSTEM).assertThrow!DBusException();
}
}
diff --git a/source/ddbus/util.d b/source/ddbus/util.d
index 4254a19..7ffc108 100644
--- a/source/ddbus/util.d
+++ b/source/ddbus/util.d
@@ -26,12 +26,10 @@ auto byDictionaryEntries(K, V)(V[K] aa) {
Its meaning became unclear when support for Phobos-style variants was added.
It seemed best to remove it at that point.
+/
-deprecated("Use std.traits.isInstanceOf instead.")
-template isVariant(T) {
- static if(isBasicType!T || isInputRange!T) {
+deprecated("Use std.traits.isInstanceOf instead.") template isVariant(T) {
+ static if (isBasicType!T || isInputRange!T) {
enum isVariant = false;
- } else static if(__traits(compiles, TemplateOf!T)
- && __traits(isSame, TemplateOf!T, Variant)) {
+ } else static if (__traits(compiles, TemplateOf!T) && __traits(isSame, TemplateOf!T, Variant)) {
enum isVariant = true;
} else {
enum isVariant = false;
@@ -44,38 +42,27 @@ template VariantType(T) {
template allCanDBus(TS...) {
static if (TS.length == 0) {
- enum allCanDBus = true;
- } else static if(!canDBus!(TS[0])) {
+ enum allCanDBus = true;
+ } else static if (!canDBus!(TS[0])) {
enum allCanDBus = false;
} else {
- enum allCanDBus = allCanDBus!(TS[1..$]);
+ enum allCanDBus = allCanDBus!(TS[1 .. $]);
}
}
/++
AliasSeq of all basic types in terms of the DBus typesystem
+/
-package // Don't add to the API yet, 'cause I intend to move it later
-alias BasicTypes = AliasSeq!(
- bool,
- byte,
- short,
- ushort,
- int,
- uint,
- long,
- ulong,
- double,
- string,
- ObjectPath
-);
+package // Don't add to the API yet, 'cause I intend to move it later
+alias BasicTypes = AliasSeq!(bool, byte, short, ushort, int, uint, long, ulong,
+ double, string, ObjectPath);
template basicDBus(T) {
- static if(staticIndexOf!(T, BasicTypes) >= 0) {
+ static if (staticIndexOf!(T, BasicTypes) >= 0) {
enum basicDBus = true;
- } else static if(is(T B == enum)) {
+ } else static if (is(T B == enum)) {
enum basicDBus = basicDBus!B;
- } else static if(isInstanceOf!(BitFlags, T)) {
+ } else static if (isInstanceOf!(BitFlags, T)) {
alias TemplateArgsOf!T[0] E;
enum basicDBus = basicDBus!E;
} else {
@@ -84,24 +71,24 @@ template basicDBus(T) {
}
template canDBus(T) {
- static if(basicDBus!T || is(T == DBusAny)) {
+ static if (basicDBus!T || is(T == DBusAny)) {
enum canDBus = true;
- } else static if(isInstanceOf!(Variant, T)) {
+ } else static if (isInstanceOf!(Variant, T)) {
enum canDBus = canDBus!(VariantType!T);
- } else static if(isInstanceOf!(VariantN, T)) {
+ } else static if (isInstanceOf!(VariantN, T)) {
// Phobos-style variants are supported if limited to DBus compatible types.
enum canDBus = (T.AllowedTypes.length > 0) && allCanDBus!(T.AllowedTypes);
- } else static if(isTuple!T) {
+ } else static if (isTuple!T) {
enum canDBus = allCanDBus!(T.Types);
- } else static if(isInputRange!T) {
- static if(is(ElementType!T == DictionaryEntry!(K, V), K, V)) {
+ } else static if (isInputRange!T) {
+ static if (is(ElementType!T == DictionaryEntry!(K, V), K, V)) {
enum canDBus = basicDBus!K && canDBus!V;
} else {
enum canDBus = canDBus!(ElementType!T);
}
- } else static if(isAssociativeArray!T) {
+ } else static if (isAssociativeArray!T) {
enum canDBus = basicDBus!(KeyType!T) && canDBus!(ValueType!T);
- } else static if(is(T == struct) && !isInstanceOf!(DictionaryEntry, T)) {
+ } else static if (is(T == struct) && !isInstanceOf!(DictionaryEntry, T)) {
enum canDBus = allCanDBus!(AllowedFieldTypes!T);
} else {
enum canDBus = false;
@@ -110,60 +97,63 @@ template canDBus(T) {
unittest {
import dunit.toolkit;
+
(canDBus!int).assertTrue();
(canDBus!(int[])).assertTrue();
- (allCanDBus!(int,string,bool)).assertTrue();
- (canDBus!(Tuple!(int[],bool,Variant!short))).assertTrue();
- (canDBus!(Tuple!(int[],int[string]))).assertTrue();
+ (allCanDBus!(int, string, bool)).assertTrue();
+ (canDBus!(Tuple!(int[], bool, Variant!short))).assertTrue();
+ (canDBus!(Tuple!(int[], int[string]))).assertTrue();
(canDBus!(int[string])).assertTrue();
}
-string typeSig(T)() if(canDBus!T) {
- static if(is(T == byte)) {
+string typeSig(T)()
+ if (canDBus!T) {
+ static if (is(T == byte)) {
return "y";
- } else static if(is(T == bool)) {
+ } else static if (is(T == bool)) {
return "b";
- } else static if(is(T == short)) {
+ } else static if (is(T == short)) {
return "n";
- } else static if(is(T == ushort)) {
+ } else static if (is(T == ushort)) {
return "q";
- } else static if(is(T == int)) {
+ } else static if (is(T == int)) {
return "i";
- } else static if(is(T == uint)) {
+ } else static if (is(T == uint)) {
return "u";
- } else static if(is(T == long)) {
+ } else static if (is(T == long)) {
return "x";
- } else static if(is(T == ulong)) {
+ } else static if (is(T == ulong)) {
return "t";
- } else static if(is(T == double)) {
+ } else static if (is(T == double)) {
return "d";
- } else static if(is(T == string)) {
+ } else static if (is(T == string)) {
return "s";
- } else static if(is(T == ObjectPath)) {
+ } else static if (is(T == ObjectPath)) {
return "o";
- } else static if(isInstanceOf!(Variant, T) || isInstanceOf!(VariantN, T)) {
+ } else static if (isInstanceOf!(Variant, T) || isInstanceOf!(VariantN, T)) {
return "v";
- } else static if(is(T B == enum)) {
+ } else static if (is(T B == enum)) {
return typeSig!B;
- } else static if(isInstanceOf!(BitFlags, T)) {
+ } else static if (isInstanceOf!(BitFlags, T)) {
alias TemplateArgsOf!T[0] E;
return typeSig!E;
- } else static if(is(T == DBusAny)) {
- static assert(false, "Cannot determine type signature of DBusAny. Change to Variant!DBusAny if a variant was desired.");
- } else static if(isTuple!T) {
+ } else static if (is(T == DBusAny)) {
+ static assert(false,
+ "Cannot determine type signature of DBusAny. Change to Variant!DBusAny if a variant was desired.");
+ } else static if (isTuple!T) {
string sig = "(";
- foreach(i, S; T.Types) {
+ foreach (i, S; T.Types) {
sig ~= typeSig!S();
- }
+ }
sig ~= ")";
return sig;
- } else static if(isInputRange!T) {
+ } else static if (isInputRange!T) {
return "a" ~ typeSig!(ElementType!T)();
- } else static if(isAssociativeArray!T) {
+ } else static if (isAssociativeArray!T) {
return "a{" ~ typeSig!(KeyType!T) ~ typeSig!(ValueType!T) ~ "}";
- } else static if(is(T == struct)) {
+ } else static if (is(T == struct)) {
string sig = "(";
- foreach(i, S; AllowedFieldTypes!T) {
+ foreach (i, S; AllowedFieldTypes!T) {
sig ~= typeSig!S();
}
sig ~= ")";
@@ -171,66 +161,99 @@ string typeSig(T)() if(canDBus!T) {
}
}
-string typeSig(T)() if(isInstanceOf!(DictionaryEntry, T)) {
+string typeSig(T)()
+ if (isInstanceOf!(DictionaryEntry, T)) {
alias typeof(T.key) K;
alias typeof(T.value) V;
return "{" ~ typeSig!K ~ typeSig!V ~ '}';
}
-string[] typeSigReturn(T)() if(canDBus!T) {
- static if(is(T == Tuple!TS, TS...))
+string[] typeSigReturn(T)()
+ if (canDBus!T) {
+ static if (is(T == Tuple!TS, TS...))
return typeSigArr!TS;
else
return [typeSig!T];
}
-string typeSigAll(TS...)() if(allCanDBus!TS) {
+string typeSigAll(TS...)()
+ if (allCanDBus!TS) {
string sig = "";
- foreach(i,T; TS) {
+ foreach (i, T; TS) {
sig ~= typeSig!T();
}
return sig;
}
-string[] typeSigArr(TS...)() if(allCanDBus!TS) {
+string[] typeSigArr(TS...)()
+ if (allCanDBus!TS) {
string[] sig = [];
- foreach(i,T; TS) {
+ foreach (i, T; TS) {
sig ~= typeSig!T();
}
return sig;
}
-int typeCode(T)() if(canDBus!T) {
+int typeCode(T)()
+ if (canDBus!T) {
int code = typeSig!T()[0];
return (code != '(') ? code : 'r';
}
-int typeCode(T)() if(isInstanceOf!(DictionaryEntry, T) && canDBus!(T[])) {
+int typeCode(T)()
+ if (isInstanceOf!(DictionaryEntry, T) && canDBus!(T[])) {
return 'e';
}
unittest {
import dunit.toolkit;
+
// basics
typeSig!int().assertEqual("i");
typeSig!bool().assertEqual("b");
typeSig!string().assertEqual("s");
typeSig!(Variant!int)().assertEqual("v");
// enums
- enum E : byte { a, b, c }
+ enum E : byte {
+ a,
+ b,
+ c
+ }
+
typeSig!E().assertEqual(typeSig!byte());
- enum U : string { One = "One", Two = "Two" }
+ enum U : string {
+ One = "One",
+ Two = "Two"
+ }
+
typeSig!U().assertEqual(typeSig!string());
// bit flags
- enum F : uint { a = 1, b = 2, c = 4 }
+ enum F : uint {
+ a = 1,
+ b = 2,
+ c = 4
+ }
+
typeSig!(BitFlags!F)().assertEqual(typeSig!uint());
// tuples (represented as structs in DBus)
- typeSig!(Tuple!(int,string,string)).assertEqual("(iss)");
- typeSig!(Tuple!(int,string,Variant!int,Tuple!(int,"k",double,"x"))).assertEqual("(isv(id))");
+ typeSig!(Tuple!(int, string, string)).assertEqual("(iss)");
+ typeSig!(Tuple!(int, string, Variant!int, Tuple!(int, "k", double, "x"))).assertEqual(
+ "(isv(id))");
// structs
- struct S1 { int a; double b; string s; }
+ struct S1 {
+ int a;
+ double b;
+ string s;
+ }
+
typeSig!S1.assertEqual("(ids)");
- struct S2 { Variant!int c; string d; S1 e; uint f; }
+ struct S2 {
+ Variant!int c;
+ string d;
+ S1 e;
+ uint f;
+ }
+
typeSig!S2.assertEqual("(vs(ids)u)");
// arrays
typeSig!(int[]).assertEqual("ai");
@@ -240,7 +263,7 @@ unittest {
typeSig!(int[string]).assertEqual("a{si}");
typeSig!(DictionaryEntry!(string, int)[]).assertEqual("a{si}");
// multiple arguments
- typeSigAll!(int,bool).assertEqual("ib");
+ typeSigAll!(int, bool).assertEqual("ib");
// Phobos-style variants
canDBus!(std.variant.Variant).assertFalse();
typeSig!(std.variant.Algebraic!(int, double, string)).assertEqual("v");
@@ -251,17 +274,18 @@ unittest {
// ctfe-capable
static string sig = typeSig!ulong();
sig.assertEqual("t");
- static string sig2 = typeSig!(Tuple!(int,string,string));
- sig2.assertEqual("(iss)");
- static string sig3 = typeSigAll!(int,string,string);
- sig3.assertEqual("iss");
+ static string sig2 = typeSig!(Tuple!(int, string, string));
+ sig2.assertEqual("(iss)");
+ static string sig3 = typeSigAll!(int, string, string);
+ sig3.assertEqual("iss");
}
-private template AllowedFieldTypes(S) if (is(S == struct)) {
+private template AllowedFieldTypes(S)
+ if (is(S == struct)) {
import ddbus.attributes : isAllowedField;
import std.meta : Filter, staticMap;
+
static alias TypeOf(alias sym) = typeof(sym);
- alias AllowedFieldTypes =
- staticMap!(TypeOf, Filter!(isAllowedField, S.tupleof));
+ alias AllowedFieldTypes = staticMap!(TypeOf, Filter!(isAllowedField, S.tupleof));
}