Merge pull request #25 from trishume/objpath-improv2

ObjectPath Improvements
This commit is contained in:
thaven 2017-11-04 11:01:07 +01:00 committed by GitHub
commit 279c3ab00b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 82 additions and 8 deletions

View file

@ -8,6 +8,10 @@ import std.string;
import std.traits;
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.conn = conn;
this.dest = dest.toStringz();

View file

@ -18,8 +18,8 @@ public import ddbus.exception : wrapErrors, DBusException;
struct ObjectPath {
private string _value;
this(string objPath) {
enforce(_isValid(objPath));
this(string objPath) pure @safe {
enforce(isValid(objPath));
_value = objPath;
}
@ -27,17 +27,73 @@ struct ObjectPath {
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);
}
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;
}
private static bool _isValid(string objPath) {
import std.regex : matchFirst, ctRegex;
return cast(bool) objPath.matchFirst(ctRegex!("^((/[0-9A-Za-z_]+)+|/)$"));
ObjectPath opBinary(string op : "~")(string rhs) const pure @safe {
if (!rhs.startsWith("/"))
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("/path/with/TrailingSlash/").assertThrow();
ObjectPath("/path/without/TrailingSlash").assertNotThrown();
string path = "/org/freedesktop/DBus";
auto obj = ObjectPath(path);
obj.toString().assertEqual(path);
obj.value.assertEqual(path);
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
struct DBusAny {
/// DBus type of the value (never 'v'), see typeSig!T