Merge pull request #25 from trishume/objpath-improv2
ObjectPath Improvements
This commit is contained in:
commit
279c3ab00b
|
@ -8,6 +8,10 @@ import std.string;
|
||||||
import std.traits;
|
import std.traits;
|
||||||
|
|
||||||
class PathIface {
|
class PathIface {
|
||||||
|
this(Connection conn, string dest, ObjectPath path, string iface) {
|
||||||
|
this(conn, dest, path.value, iface);
|
||||||
|
}
|
||||||
|
|
||||||
this(Connection conn, string dest, string path, string iface) {
|
this(Connection conn, string dest, string path, string iface) {
|
||||||
this.conn = conn;
|
this.conn = conn;
|
||||||
this.dest = dest.toStringz();
|
this.dest = dest.toStringz();
|
||||||
|
|
|
@ -18,8 +18,8 @@ public import ddbus.exception : wrapErrors, DBusException;
|
||||||
struct ObjectPath {
|
struct ObjectPath {
|
||||||
private string _value;
|
private string _value;
|
||||||
|
|
||||||
this(string objPath) {
|
this(string objPath) pure @safe {
|
||||||
enforce(_isValid(objPath));
|
enforce(isValid(objPath));
|
||||||
_value = objPath;
|
_value = objPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,17 +27,73 @@ struct ObjectPath {
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t toHash() const pure nothrow @trusted {
|
/++
|
||||||
|
Returns the string representation of this ObjectPath.
|
||||||
|
+/
|
||||||
|
string value() const pure @nogc nothrow @safe {
|
||||||
|
return _value;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t toHash() const pure @nogc nothrow @trusted {
|
||||||
return hashOf(_value);
|
return hashOf(_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool opEquals(ref const typeof(this) b) const pure nothrow @safe {
|
bool opEquals(ref const typeof(this) b) const pure @nogc nothrow @safe {
|
||||||
return _value == b._value;
|
return _value == b._value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool _isValid(string objPath) {
|
ObjectPath opBinary(string op : "~")(string rhs) const pure @safe {
|
||||||
import std.regex : matchFirst, ctRegex;
|
if (!rhs.startsWith("/"))
|
||||||
return cast(bool) objPath.matchFirst(ctRegex!("^((/[0-9A-Za-z_]+)+|/)$"));
|
return opBinary!"~"(ObjectPath("/" ~ rhs));
|
||||||
|
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) {
|
||||||
|
assert(ObjectPath.isValid(v._value));
|
||||||
|
} body {
|
||||||
|
ObjectPath ret;
|
||||||
|
|
||||||
|
if (_value == "/")
|
||||||
|
ret._value = rhs._value;
|
||||||
|
else
|
||||||
|
ret._value = _value ~ rhs._value;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void opOpAssign(string op : "~")(string rhs) pure @safe {
|
||||||
|
_value = opBinary!"~"(rhs)._value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void opOpAssign(string op : "~")(ObjectPath rhs) pure @safe {
|
||||||
|
_value = opBinary!"~"(rhs)._value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/++
|
||||||
|
Returns: `false` for empty strings or strings that don't match the
|
||||||
|
pattern `(/[0-9A-Za-z_]+)+|/`.
|
||||||
|
+/
|
||||||
|
static bool isValid(string objPath) pure @nogc nothrow @safe {
|
||||||
|
import std.ascii : isAlphaNum;
|
||||||
|
|
||||||
|
if (!objPath.length)
|
||||||
|
return false;
|
||||||
|
if (objPath == "/")
|
||||||
|
return true;
|
||||||
|
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 == '_'
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,12 +102,26 @@ unittest {
|
||||||
|
|
||||||
ObjectPath("some.invalid/object_path").assertThrow();
|
ObjectPath("some.invalid/object_path").assertThrow();
|
||||||
ObjectPath("/path/with/TrailingSlash/").assertThrow();
|
ObjectPath("/path/with/TrailingSlash/").assertThrow();
|
||||||
|
ObjectPath("/path/without/TrailingSlash").assertNotThrown();
|
||||||
string path = "/org/freedesktop/DBus";
|
string path = "/org/freedesktop/DBus";
|
||||||
auto obj = ObjectPath(path);
|
auto obj = ObjectPath(path);
|
||||||
obj.toString().assertEqual(path);
|
obj.value.assertEqual(path);
|
||||||
obj.toHash().assertEqual(path.hashOf);
|
obj.toHash().assertEqual(path.hashOf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unittest {
|
||||||
|
import dunit.toolkit;
|
||||||
|
|
||||||
|
ObjectPath a = ObjectPath("/org/freedesktop");
|
||||||
|
a.assertEqual(ObjectPath("/org/freedesktop"));
|
||||||
|
a ~= ObjectPath("/UPower");
|
||||||
|
a.assertEqual(ObjectPath("/org/freedesktop/UPower"));
|
||||||
|
a ~= "Device";
|
||||||
|
a.assertEqual(ObjectPath("/org/freedesktop/UPower/Device"));
|
||||||
|
(a ~ "0").assertEqual(ObjectPath("/org/freedesktop/UPower/Device/0"));
|
||||||
|
a.assertEqual(ObjectPath("/org/freedesktop/UPower/Device"));
|
||||||
|
}
|
||||||
|
|
||||||
/// Structure allowing typeless parameters
|
/// Structure allowing typeless parameters
|
||||||
struct DBusAny {
|
struct DBusAny {
|
||||||
/// DBus type of the value (never 'v'), see typeSig!T
|
/// DBus type of the value (never 'v'), see typeSig!T
|
||||||
|
|
Loading…
Reference in a new issue