mirror of
https://github.com/logos-storage/nim-datastore.git
synced 2026-01-02 13:43:11 +00:00
simplify key api
This commit is contained in:
parent
2769ce1de2
commit
ed6842b743
@ -15,11 +15,11 @@ push: {.upraises: [].}
|
||||
|
||||
type
|
||||
Namespace* = object
|
||||
field: ?string
|
||||
value: string
|
||||
field*: string
|
||||
value*: string
|
||||
|
||||
Key* = object
|
||||
namespaces: seq[Namespace]
|
||||
namespaces*: seq[Namespace]
|
||||
|
||||
const
|
||||
delimiter = ":"
|
||||
@ -32,11 +32,8 @@ proc init*(
|
||||
T: type Namespace,
|
||||
field, value: string): ?!T =
|
||||
|
||||
if value == "":
|
||||
return failure "value string must not be empty"
|
||||
|
||||
if value.strip == "":
|
||||
return failure "value string must not be all whitespace"
|
||||
return failure "value string must not be all whitespace or empty"
|
||||
|
||||
if value.contains(delimiter):
|
||||
return failure "value string must not contain delimiter \"" &
|
||||
@ -58,19 +55,11 @@ proc init*(
|
||||
return failure "field string must not contain separator \"" &
|
||||
separator & "\""
|
||||
|
||||
success T(field: field.some, value: value)
|
||||
else:
|
||||
success T(field: string.none, value: value)
|
||||
|
||||
proc init*(
|
||||
T: type Namespace,
|
||||
id: string): ?!T =
|
||||
|
||||
if id == "":
|
||||
return failure "id string must not be empty"
|
||||
success T(field: field, value: value)
|
||||
|
||||
proc init*(T: type Namespace, id: string): ?!T =
|
||||
if id.strip == "":
|
||||
return failure "id string must not be all whitespace"
|
||||
return failure "id string must not be all whitespace or empty"
|
||||
|
||||
if id.contains(separator):
|
||||
return failure "id string must not contain separator \"" & separator & "\""
|
||||
@ -79,98 +68,45 @@ proc init*(
|
||||
return failure "value in id string \"[field]" & delimiter &
|
||||
"[value]\" must not be empty"
|
||||
|
||||
let
|
||||
s = id.split(delimiter)
|
||||
|
||||
if s.len > 2:
|
||||
if id.count(delimiter) > 1:
|
||||
return failure "id string must not contain more than one delimiter \"" &
|
||||
delimiter & "\""
|
||||
|
||||
var
|
||||
field: ?string
|
||||
value: string
|
||||
let
|
||||
(field, value) = block:
|
||||
let parts = id.split(delimiter)
|
||||
if parts.len > 1:
|
||||
(parts[0], parts[^1])
|
||||
else:
|
||||
("", parts[^1])
|
||||
|
||||
if s.len == 1:
|
||||
value = s[0]
|
||||
else:
|
||||
value = s[1]
|
||||
|
||||
if value == "":
|
||||
return failure "value in id string \"[field]" & delimiter &
|
||||
"[value]\" must not be empty"
|
||||
|
||||
if value.strip == "":
|
||||
return failure "value in id string \"[field]" & delimiter &
|
||||
"[value]\" must not be all whitespace"
|
||||
|
||||
else:
|
||||
let
|
||||
f = s[0]
|
||||
|
||||
if f != "":
|
||||
if f.strip == "":
|
||||
return failure "field in id string \"[field]" & delimiter &
|
||||
"[value]\" must not be all whitespace"
|
||||
|
||||
else:
|
||||
field = f.some
|
||||
|
||||
success T(field: field, value: value)
|
||||
|
||||
proc value*(self: Namespace): string =
|
||||
self.value
|
||||
|
||||
proc field*(self: Namespace): ?string =
|
||||
self.field
|
||||
|
||||
proc `type`*(self: Namespace): ?string =
|
||||
self.field
|
||||
|
||||
proc kind*(self: Namespace): ?string =
|
||||
self.`type`
|
||||
T.init(field, value)
|
||||
|
||||
proc id*(self: Namespace): string =
|
||||
if field =? self.field: field & delimiter & self.value
|
||||
else: self.value
|
||||
if self.field.len > 0:
|
||||
self.field & delimiter & self.value
|
||||
else:
|
||||
self.value
|
||||
|
||||
proc `$`*(namespace: Namespace): string =
|
||||
"Namespace(" & namespace.id & ")"
|
||||
|
||||
proc init*(
|
||||
T: type Key,
|
||||
namespaces: varargs[Namespace]): ?!T =
|
||||
|
||||
proc init*(T: type Key, namespaces: varargs[Namespace]): ?!T =
|
||||
if namespaces.len == 0:
|
||||
failure "namespaces must contain at least one Namespace"
|
||||
else:
|
||||
success T(namespaces: @namespaces)
|
||||
|
||||
proc init*(
|
||||
T: type Key,
|
||||
namespaces: varargs[string]): ?!T =
|
||||
|
||||
proc init*(T: type Key, namespaces: varargs[string]): ?!T =
|
||||
if namespaces.len == 0:
|
||||
failure "namespaces must contain at least one Namespace id string"
|
||||
else:
|
||||
var
|
||||
nss: seq[Namespace]
|
||||
|
||||
for s in namespaces:
|
||||
let
|
||||
nsRes = Namespace.init(s)
|
||||
|
||||
if nsRes.isErr:
|
||||
return failure "namespaces contains an invalid Namespace: " &
|
||||
nsRes.error.msg
|
||||
|
||||
nss.add nsRes.get
|
||||
|
||||
success T(namespaces: nss)
|
||||
|
||||
proc init*(
|
||||
T: type Key,
|
||||
id: string): ?!T =
|
||||
success T(
|
||||
namespaces: namespaces.mapIt(
|
||||
?Namespace.init(it)
|
||||
))
|
||||
|
||||
proc init*(T: type Key, id: string): ?!T =
|
||||
if id == "":
|
||||
return failure "id string must contain at least one Namespace"
|
||||
|
||||
@ -184,17 +120,7 @@ proc init*(
|
||||
return failure "id string must not contain only one or more separator " &
|
||||
"\"" & separator & "\""
|
||||
|
||||
let
|
||||
keyRes = Key.init(nsStrs)
|
||||
|
||||
if keyRes.isErr:
|
||||
return failure "id string contains an invalid Namespace:" &
|
||||
keyRes.error.msg.split(":")[1..^1].join("").replace("\"\"", "\":\"")
|
||||
|
||||
keyRes
|
||||
|
||||
proc namespaces*(self: Key): seq[Namespace] =
|
||||
self.namespaces
|
||||
Key.init(nsStrs)
|
||||
|
||||
proc list*(self: Key): seq[Namespace] =
|
||||
self.namespaces
|
||||
@ -202,22 +128,15 @@ proc list*(self: Key): seq[Namespace] =
|
||||
proc random*(T: type Key): string =
|
||||
$genOid()
|
||||
|
||||
template `[]`*(
|
||||
key: Key,
|
||||
x: auto): auto =
|
||||
|
||||
template `[]`*(key: Key, x: auto): auto =
|
||||
key.namespaces[x]
|
||||
|
||||
proc len*(self: Key): int =
|
||||
self.namespaces.len
|
||||
|
||||
iterator items*(key: Key): Namespace =
|
||||
var
|
||||
i = 0
|
||||
|
||||
while i < key.len:
|
||||
yield key[i]
|
||||
inc i
|
||||
for k in key.namespaces:
|
||||
yield k
|
||||
|
||||
proc reversed*(self: Key): Key =
|
||||
Key(namespaces: self.namespaces.reversed)
|
||||
@ -226,55 +145,15 @@ proc reverse*(self: Key): Key =
|
||||
self.reversed
|
||||
|
||||
proc name*(self: Key): string =
|
||||
self[^1].value
|
||||
if self.len > 0:
|
||||
return self[^1].value
|
||||
|
||||
proc `type`*(self: Key): ?string =
|
||||
self[^1].field
|
||||
proc `type`*(self: Key): string =
|
||||
if self.len > 0:
|
||||
return self[^1].field
|
||||
|
||||
proc kind*(self: Key): ?string =
|
||||
self.`type`
|
||||
|
||||
proc instance*(
|
||||
self: Key,
|
||||
value: Namespace): Key =
|
||||
|
||||
let
|
||||
last = self[^1]
|
||||
|
||||
inst =
|
||||
if last.field.isSome:
|
||||
@[Namespace(field: last.field, value: value.value)]
|
||||
else:
|
||||
@[Namespace(field: last.value.some, value: value.value)]
|
||||
|
||||
namespaces =
|
||||
if self.namespaces.len == 1:
|
||||
inst
|
||||
else:
|
||||
self.namespaces[0..^2] & inst
|
||||
|
||||
Key(namespaces: namespaces)
|
||||
|
||||
proc instance*(self, value: Key): Key =
|
||||
self.instance(value[^1])
|
||||
|
||||
proc instance*(self, value: Namespace): Key =
|
||||
Key(namespaces: @[self]).instance(value)
|
||||
|
||||
proc instance*(
|
||||
self: Namespace,
|
||||
value: Key): Key =
|
||||
|
||||
self.instance(value[^1])
|
||||
|
||||
proc instance*(
|
||||
self: Key,
|
||||
id: string): ?!Key =
|
||||
|
||||
without key =? Key.init(id), e:
|
||||
return failure e
|
||||
|
||||
success self.instance(key)
|
||||
proc id*(self: Key): string =
|
||||
separator & self.namespaces.mapIt(it.id).join(separator)
|
||||
|
||||
proc isTopLevel*(self: Key): bool =
|
||||
self.len == 1
|
||||
@ -285,43 +164,22 @@ proc parent*(self: Key): ?!Key =
|
||||
else:
|
||||
success Key(namespaces: self.namespaces[0..^2])
|
||||
|
||||
proc parent*(self: ?!Key): ?!Key =
|
||||
let
|
||||
key = ? self
|
||||
|
||||
key.parent
|
||||
|
||||
proc path*(self: Key): ?!Key =
|
||||
let
|
||||
parent = ? self.parent
|
||||
|
||||
without kind =? self[^1].kind:
|
||||
if self[^1].field == "":
|
||||
return success parent
|
||||
|
||||
success Key(namespaces: parent.namespaces & @[Namespace(value: kind)])
|
||||
|
||||
proc path*(self: ?!Key): ?!Key =
|
||||
let
|
||||
key = ? self
|
||||
|
||||
key.path
|
||||
|
||||
proc child*(
|
||||
self: Key,
|
||||
ns: Namespace): Key =
|
||||
success Key(namespaces: parent.namespaces & @[Namespace(value: self[^1].field)])
|
||||
|
||||
proc child*(self: Key, ns: Namespace): Key =
|
||||
Key(namespaces: self.namespaces & @[ns])
|
||||
|
||||
proc `/`*(
|
||||
self: Key,
|
||||
ns: Namespace): Key =
|
||||
|
||||
proc `/`*(self: Key, ns: Namespace): Key =
|
||||
self.child(ns)
|
||||
|
||||
proc child*(
|
||||
self: Key,
|
||||
namespaces: varargs[Namespace]): Key =
|
||||
|
||||
proc child*(self: Key, namespaces: varargs[Namespace]): Key =
|
||||
Key(namespaces: self.namespaces & @namespaces)
|
||||
|
||||
proc child*(self, key: Key): Key =
|
||||
@ -330,34 +188,13 @@ proc child*(self, key: Key): Key =
|
||||
proc `/`*(self, key: Key): Key =
|
||||
self.child(key)
|
||||
|
||||
proc child*(
|
||||
self: Key,
|
||||
keys: varargs[Key]): Key =
|
||||
|
||||
proc child*(self: Key, keys: varargs[Key]): Key =
|
||||
Key(namespaces: self.namespaces & concat(keys.mapIt(it.namespaces)))
|
||||
|
||||
proc child*(
|
||||
self: Key,
|
||||
ids: varargs[string]): ?!Key =
|
||||
|
||||
let
|
||||
ids = ids.filterIt(it != "")
|
||||
|
||||
var
|
||||
keys: seq[Key]
|
||||
|
||||
for id in ids:
|
||||
let
|
||||
key = ? Key.init(id)
|
||||
|
||||
keys.add key
|
||||
|
||||
success self.child(keys)
|
||||
|
||||
proc `/`*(
|
||||
self: Key,
|
||||
id: string): ?!Key =
|
||||
proc child*(self: Key, ids: varargs[string]): ?!Key =
|
||||
success self.child(ids.filterIt(it != "").mapIt( ?Key.init(it) ))
|
||||
|
||||
proc `/`*(self: Key, id: string): ?!Key =
|
||||
self.child(id)
|
||||
|
||||
proc isAncestorOf*(self, other: Key): bool =
|
||||
@ -367,8 +204,5 @@ proc isAncestorOf*(self, other: Key): bool =
|
||||
proc isDescendantOf*(self, other: Key): bool =
|
||||
other.isAncestorOf(self)
|
||||
|
||||
proc id*(self: Key): string =
|
||||
separator & self.namespaces.mapIt(it.id).join(separator)
|
||||
|
||||
proc `$`*(key: Key): string =
|
||||
"Key(" & key.id & ")"
|
||||
|
||||
@ -1,310 +1,179 @@
|
||||
import std/options
|
||||
|
||||
import pkg/stew/results
|
||||
import pkg/unittest2
|
||||
import pkg/questionable
|
||||
import pkg/questionable/results
|
||||
|
||||
import ../../datastore/key
|
||||
|
||||
suite "Namespace":
|
||||
test "init":
|
||||
var
|
||||
nsRes: Result[Namespace, ref CatchableError]
|
||||
test "init failure":
|
||||
check:
|
||||
Namespace.init("a", "").isFailure
|
||||
Namespace.init("a", " ").isFailure
|
||||
Namespace.init("a", ":").isFailure
|
||||
Namespace.init("a", "/").isFailure
|
||||
Namespace.init(":", "b").isFailure
|
||||
Namespace.init("/", "b").isFailure
|
||||
Namespace.init(" ", "b").isFailure
|
||||
Namespace.init("").isFailure
|
||||
Namespace.init(" ").isFailure
|
||||
Namespace.init("/").isFailure
|
||||
Namespace.init(":").isFailure
|
||||
Namespace.init("a:b:c").isFailure
|
||||
Namespace.init("a:").isFailure
|
||||
Namespace.init("a: ").isFailure
|
||||
Namespace.init(" :b").isFailure
|
||||
|
||||
nsRes = Namespace.init("a", "")
|
||||
|
||||
check: nsRes.isErr
|
||||
|
||||
nsRes = Namespace.init("a", " ")
|
||||
|
||||
check: nsRes.isErr
|
||||
|
||||
nsRes = Namespace.init("a", ":")
|
||||
|
||||
check: nsRes.isErr
|
||||
|
||||
nsRes = Namespace.init("a", "/")
|
||||
|
||||
check: nsRes.isErr
|
||||
|
||||
nsRes = Namespace.init(":", "b")
|
||||
|
||||
check: nsRes.isErr
|
||||
|
||||
nsRes = Namespace.init("/", "b")
|
||||
|
||||
check: nsRes.isErr
|
||||
|
||||
nsRes = Namespace.init("", "b")
|
||||
|
||||
check: nsRes.isOk
|
||||
|
||||
nsRes = Namespace.init(" ", "b")
|
||||
|
||||
check: nsRes.isErr
|
||||
|
||||
nsRes = Namespace.init("a", "b")
|
||||
|
||||
check: nsRes.isOk
|
||||
|
||||
nsRes = Namespace.init("")
|
||||
|
||||
check: nsRes.isErr
|
||||
|
||||
nsRes = Namespace.init(" ")
|
||||
|
||||
check: nsRes.isErr
|
||||
|
||||
nsRes = Namespace.init("/")
|
||||
|
||||
check: nsRes.isErr
|
||||
|
||||
nsRes = Namespace.init(":")
|
||||
|
||||
check: nsRes.isErr
|
||||
|
||||
nsRes = Namespace.init("a:b:c")
|
||||
|
||||
check: nsRes.isErr
|
||||
|
||||
nsRes = Namespace.init("a")
|
||||
|
||||
check: nsRes.isOk
|
||||
|
||||
nsRes = Namespace.init("a:")
|
||||
|
||||
check: nsRes.isErr
|
||||
|
||||
nsRes = Namespace.init("a: ")
|
||||
|
||||
check: nsRes.isErr
|
||||
|
||||
nsRes = Namespace.init(" :b")
|
||||
|
||||
check: nsRes.isErr
|
||||
|
||||
nsRes = Namespace.init("a:b")
|
||||
|
||||
check: nsRes.isOk
|
||||
|
||||
nsRes = Namespace.init(":b")
|
||||
|
||||
check: nsRes.isOk
|
||||
test "init success":
|
||||
check:
|
||||
Namespace.init("", "b").isSuccess
|
||||
Namespace.init("a", "b").isSuccess
|
||||
Namespace.init("a").isSuccess
|
||||
Namespace.init("a:b").isSuccess
|
||||
Namespace.init(":b").isSuccess
|
||||
|
||||
test "accessors":
|
||||
var
|
||||
ns: Namespace
|
||||
|
||||
ns = Namespace.init("", "b").get
|
||||
ns = Namespace.init("", "b").tryGet()
|
||||
|
||||
check:
|
||||
ns.value == "b"
|
||||
ns.field.isNone
|
||||
ns.field == ""
|
||||
|
||||
ns = Namespace.init("a", "b").get
|
||||
ns = Namespace.init("a", "b").tryGet()
|
||||
|
||||
check:
|
||||
ns.value == "b"
|
||||
ns.field.isSome and ns.field.get == "a"
|
||||
ns.field != "" and ns.field == "a"
|
||||
|
||||
ns = Namespace.init(":b").get
|
||||
ns = Namespace.init(":b").tryGet()
|
||||
|
||||
check:
|
||||
ns.value == "b"
|
||||
ns.field.isNone
|
||||
ns.field == ""
|
||||
|
||||
ns = Namespace.init("a:b").get
|
||||
ns = Namespace.init("a:b").tryGet()
|
||||
|
||||
check:
|
||||
ns.value == "b"
|
||||
ns.field.isSome and ns.field.get == "a"
|
||||
|
||||
check:
|
||||
ns.`type`.get == ns.field.get
|
||||
ns.kind.get == ns.field.get
|
||||
ns.field == "a"
|
||||
|
||||
test "equality":
|
||||
check:
|
||||
Namespace.init("a").get == Namespace.init("a").get
|
||||
Namespace.init("a").get != Namespace.init("b").get
|
||||
Namespace.init("", "b").get == Namespace.init("", "b").get
|
||||
Namespace.init("", "b").get == Namespace.init("b").get
|
||||
Namespace.init(":b").get == Namespace.init("b").get
|
||||
Namespace.init("", "b").get != Namespace.init("", "a").get
|
||||
Namespace.init("", "b").get != Namespace.init("a").get
|
||||
Namespace.init(":b").get != Namespace.init("a").get
|
||||
Namespace.init("a", "b").get == Namespace.init("a", "b").get
|
||||
Namespace.init("a", "b").get == Namespace.init("a:b").get
|
||||
Namespace.init("a:b").get == Namespace.init("a:b").get
|
||||
Namespace.init("a", "b").get != Namespace.init("b", "a").get
|
||||
Namespace.init("a", "b").get != Namespace.init("b:a").get
|
||||
Namespace.init("a:b").get != Namespace.init("b:a").get
|
||||
Namespace.init("a").get != Namespace.init("a:b").get
|
||||
Namespace.init("a").tryGet() == Namespace.init("a").tryGet()
|
||||
Namespace.init("a").tryGet() != Namespace.init("b").tryGet()
|
||||
Namespace.init("", "b").tryGet() == Namespace.init("", "b").tryGet()
|
||||
Namespace.init("", "b").tryGet() == Namespace.init("b").tryGet()
|
||||
Namespace.init(":b").tryGet() == Namespace.init("b").tryGet()
|
||||
Namespace.init("", "b").tryGet() != Namespace.init("", "a").tryGet()
|
||||
Namespace.init("", "b").tryGet() != Namespace.init("a").tryGet()
|
||||
Namespace.init(":b").tryGet() != Namespace.init("a").tryGet()
|
||||
Namespace.init("a", "b").tryGet() == Namespace.init("a", "b").tryGet()
|
||||
Namespace.init("a", "b").tryGet() == Namespace.init("a:b").tryGet()
|
||||
Namespace.init("a:b").tryGet() == Namespace.init("a:b").tryGet()
|
||||
Namespace.init("a", "b").tryGet() != Namespace.init("b", "a").tryGet()
|
||||
Namespace.init("a", "b").tryGet() != Namespace.init("b:a").tryGet()
|
||||
Namespace.init("a:b").tryGet() != Namespace.init("b:a").tryGet()
|
||||
Namespace.init("a").tryGet() != Namespace.init("a:b").tryGet()
|
||||
|
||||
test "serialization":
|
||||
var
|
||||
ns: Namespace
|
||||
|
||||
ns = Namespace.init(":b").get
|
||||
ns = Namespace.init(":b").tryGet()
|
||||
|
||||
check:
|
||||
ns.id == "b"
|
||||
$ns == "Namespace(" & ns.id & ")"
|
||||
|
||||
ns = Namespace.init("a:b").get
|
||||
ns = Namespace.init("a:b").tryGet()
|
||||
|
||||
check:
|
||||
ns.id == "a:b"
|
||||
$ns == "Namespace(" & ns.id & ")"
|
||||
|
||||
suite "Key":
|
||||
test "init":
|
||||
var
|
||||
keyRes: Result[Key, ref CatchableError]
|
||||
nss: seq[Namespace]
|
||||
test "init failure":
|
||||
check:
|
||||
Key.init("", "").isFailure
|
||||
Key.init(@[""]).isFailure
|
||||
Key.init(@[":"]).isFailure
|
||||
Key.init(@["/"]).isFailure
|
||||
Key.init("").isFailure
|
||||
Key.init(" ").isFailure
|
||||
Key.init("/").isFailure
|
||||
Key.init("///").isFailure
|
||||
Key.init(":").isFailure
|
||||
Key.init("::").isFailure
|
||||
Key.init("a:").isFailure
|
||||
Key.init("a:b/c:").isFailure
|
||||
|
||||
keyRes = Key.init(nss)
|
||||
|
||||
check: keyRes.isErr
|
||||
|
||||
nss = @[Namespace.init("a").get]
|
||||
|
||||
keyRes = Key.init(nss)
|
||||
|
||||
check: keyRes.isOk
|
||||
|
||||
var
|
||||
nsStrs: seq[string]
|
||||
|
||||
keyRes = Key.init(nsStrs)
|
||||
|
||||
check: keyRes.isErr
|
||||
|
||||
nsStrs = @[":"]
|
||||
|
||||
keyRes = Key.init(nsStrs)
|
||||
|
||||
check: keyRes.isErr
|
||||
|
||||
nsStrs = @["/"]
|
||||
|
||||
keyRes = Key.init(nsStrs)
|
||||
|
||||
check: keyRes.isErr
|
||||
|
||||
nsStrs = @["a:b"]
|
||||
|
||||
keyRes = Key.init(nsStrs)
|
||||
|
||||
check: keyRes.isOk
|
||||
|
||||
keyRes = Key.init("")
|
||||
|
||||
check: keyRes.isErr
|
||||
|
||||
keyRes = Key.init(" ")
|
||||
|
||||
check: keyRes.isErr
|
||||
|
||||
keyRes = Key.init("/")
|
||||
|
||||
check: keyRes.isErr
|
||||
|
||||
keyRes = Key.init("///")
|
||||
|
||||
check: keyRes.isErr
|
||||
|
||||
keyRes = Key.init(":")
|
||||
|
||||
check: keyRes.isErr
|
||||
|
||||
keyRes = Key.init("::")
|
||||
|
||||
check: keyRes.isErr
|
||||
|
||||
keyRes = Key.init("a:")
|
||||
|
||||
check: keyRes.isErr
|
||||
|
||||
keyRes = Key.init("a:b/c:")
|
||||
|
||||
check: keyRes.isErr
|
||||
|
||||
keyRes = Key.init(":b")
|
||||
|
||||
check: keyRes.isOk
|
||||
|
||||
keyRes = Key.init("a:b")
|
||||
|
||||
check: keyRes.isOk
|
||||
|
||||
keyRes = Key.init("a:b/c")
|
||||
|
||||
check: keyRes.isOk
|
||||
|
||||
keyRes = Key.init("a:b/:c")
|
||||
|
||||
check: keyRes.isOk
|
||||
|
||||
keyRes = Key.init("/a:b/c/")
|
||||
|
||||
check: keyRes.isOk
|
||||
|
||||
keyRes = Key.init("///a:b///c///")
|
||||
|
||||
check: keyRes.isOk
|
||||
test "init success":
|
||||
check:
|
||||
Key.init(Namespace.init("a").tryGet()).isSuccess
|
||||
Key.init(@["a:b"]).isSuccess
|
||||
Key.init(":b").isSuccess
|
||||
Key.init("a:b").isSuccess
|
||||
Key.init("a:b/c").isSuccess
|
||||
Key.init("a:b/:c").isSuccess
|
||||
Key.init("/a:b/c/").isSuccess
|
||||
Key.init("///a:b///c///").isSuccess
|
||||
|
||||
test "accessors":
|
||||
let
|
||||
key = Key.init("/a:b/c/d:e").get
|
||||
key = Key.init("/a:b/c/d:e").tryGet()
|
||||
|
||||
check:
|
||||
key.namespaces == @[
|
||||
Namespace.init("a:b").get,
|
||||
Namespace.init("c").get,
|
||||
Namespace.init("d:e").get
|
||||
Namespace.init("a:b").tryGet(),
|
||||
Namespace.init("c").tryGet(),
|
||||
Namespace.init("d:e").tryGet()
|
||||
]
|
||||
|
||||
key.list == key.namespaces
|
||||
|
||||
test "equality":
|
||||
check:
|
||||
Key.init(Namespace.init("a:b").get, Namespace.init("c").get).get == Key.init("a:b/c").get
|
||||
Key.init("a:b", "c").get == Key.init("a:b/c").get
|
||||
Key.init("a:b/c").get == Key.init("a:b/c").get
|
||||
Key.init(Namespace.init("a:b").get, Namespace.init("c").get).get != Key.init("c:b/a").get
|
||||
Key.init("a:b", "c").get != Key.init("c:b/a").get
|
||||
Key.init("a:b/c").get != Key.init("c:b/a").get
|
||||
Key.init("a:b/c").get == Key.init("/a:b/c/").get
|
||||
Key.init("a:b/c").get == Key.init("///a:b///c///").get
|
||||
Key.init("a:b/c").get != Key.init("///a:b///d///").get
|
||||
Key.init("a").get != Key.init("a:b").get
|
||||
Key.init("a").get != Key.init("a/b").get
|
||||
Key.init("a/b/c").get != Key.init("a/b").get
|
||||
Key.init("a:X/b/c").get == Key.init("a:X/b/c").get
|
||||
Key.init("a/b:X/c").get == Key.init("a/b:X/c").get
|
||||
Key.init("a/b/c:X").get == Key.init("a/b/c:X").get
|
||||
Key.init("a:X/b/c:X").get == Key.init("a:X/b/c:X").get
|
||||
Key.init("a:X/b:X/c").get == Key.init("a:X/b:X/c").get
|
||||
Key.init("a/b:X/c:X").get == Key.init("a/b:X/c:X").get
|
||||
Key.init("a:X/b:X/c:X").get == Key.init("a:X/b:X/c:X").get
|
||||
Key.init("a/b/c").get != Key.init("a:X/b/c").get
|
||||
Key.init("a/b/c").get != Key.init("a/b:X/c").get
|
||||
Key.init("a/b/c").get != Key.init("a/b/c:X").get
|
||||
Key.init("a/b/c").get != Key.init("a:X/b/c:X").get
|
||||
Key.init("a/b/c").get != Key.init("a:X/b:X/c").get
|
||||
Key.init("a/b/c").get != Key.init("a/b:X/c:X").get
|
||||
Key.init("a/b/c").get != Key.init("a:X/b:X/c:X").get
|
||||
Key.init(Namespace.init("a:b").tryGet(), Namespace.init("c").tryGet()).tryGet() == Key.init("a:b/c").tryGet()
|
||||
Key.init("a:b", "c").tryGet() == Key.init("a:b/c").tryGet()
|
||||
Key.init("a:b/c").tryGet() == Key.init("a:b/c").tryGet()
|
||||
Key.init(Namespace.init("a:b").tryGet(), Namespace.init("c").tryGet()).tryGet() != Key.init("c:b/a").tryGet()
|
||||
Key.init("a:b", "c").tryGet() != Key.init("c:b/a").tryGet()
|
||||
Key.init("a:b/c").tryGet() != Key.init("c:b/a").tryGet()
|
||||
Key.init("a:b/c").tryGet() == Key.init("/a:b/c/").tryGet()
|
||||
Key.init("a:b/c").tryGet() == Key.init("///a:b///c///").tryGet()
|
||||
Key.init("a:b/c").tryGet() != Key.init("///a:b///d///").tryGet()
|
||||
Key.init("a").tryGet() != Key.init("a:b").tryGet()
|
||||
Key.init("a").tryGet() != Key.init("a/b").tryGet()
|
||||
Key.init("a/b/c").tryGet() != Key.init("a/b").tryGet()
|
||||
Key.init("a:X/b/c").tryGet() == Key.init("a:X/b/c").tryGet()
|
||||
Key.init("a/b:X/c").tryGet() == Key.init("a/b:X/c").tryGet()
|
||||
Key.init("a/b/c:X").tryGet() == Key.init("a/b/c:X").tryGet()
|
||||
Key.init("a:X/b/c:X").tryGet() == Key.init("a:X/b/c:X").tryGet()
|
||||
Key.init("a:X/b:X/c").tryGet() == Key.init("a:X/b:X/c").tryGet()
|
||||
Key.init("a/b:X/c:X").tryGet() == Key.init("a/b:X/c:X").tryGet()
|
||||
Key.init("a:X/b:X/c:X").tryGet() == Key.init("a:X/b:X/c:X").tryGet()
|
||||
Key.init("a/b/c").tryGet() != Key.init("a:X/b/c").tryGet()
|
||||
Key.init("a/b/c").tryGet() != Key.init("a/b:X/c").tryGet()
|
||||
Key.init("a/b/c").tryGet() != Key.init("a/b/c:X").tryGet()
|
||||
Key.init("a/b/c").tryGet() != Key.init("a:X/b/c:X").tryGet()
|
||||
Key.init("a/b/c").tryGet() != Key.init("a:X/b:X/c").tryGet()
|
||||
Key.init("a/b/c").tryGet() != Key.init("a/b:X/c:X").tryGet()
|
||||
Key.init("a/b/c").tryGet() != Key.init("a:X/b:X/c:X").tryGet()
|
||||
|
||||
test "helpers":
|
||||
check: Key.random.len == 24
|
||||
|
||||
let
|
||||
key = Key.init("/a:b/c/d:e").get
|
||||
key = Key.init("/a:b/c/d:e").tryGet()
|
||||
|
||||
check:
|
||||
key[1] == Namespace.init("c").get
|
||||
key[1..^1] == @[Namespace.init("c").get, Namespace.init("d:e").get]
|
||||
key[^1] == Namespace.init("d:e").get
|
||||
key[1] == Namespace.init("c").tryGet()
|
||||
key[1..^1] == @[Namespace.init("c").tryGet(), Namespace.init("d:e").tryGet()]
|
||||
key[^1] == Namespace.init("d:e").tryGet()
|
||||
|
||||
check: key.len == key.namespaces.len
|
||||
|
||||
@ -316,16 +185,16 @@ suite "Key":
|
||||
|
||||
check:
|
||||
nss == @[
|
||||
Namespace.init("a:b").get,
|
||||
Namespace.init("c").get,
|
||||
Namespace.init("d:e").get
|
||||
Namespace.init("a:b").tryGet(),
|
||||
Namespace.init("c").tryGet(),
|
||||
Namespace.init("d:e").tryGet()
|
||||
]
|
||||
|
||||
check:
|
||||
key.reversed.namespaces == @[
|
||||
Namespace.init("d:e").get,
|
||||
Namespace.init("c").get,
|
||||
Namespace.init("a:b").get
|
||||
Namespace.init("d:e").tryGet(),
|
||||
Namespace.init("c").tryGet(),
|
||||
Namespace.init("a:b").tryGet()
|
||||
]
|
||||
|
||||
key.reverse == key.reversed
|
||||
@ -333,95 +202,68 @@ suite "Key":
|
||||
check: key.name == "e"
|
||||
|
||||
check:
|
||||
key.`type` == key[^1].`type`
|
||||
key.kind == key.`type`
|
||||
Key.init(":b").tryGet().isTopLevel
|
||||
not Key.init(":b/c").tryGet().isTopLevel
|
||||
|
||||
check:
|
||||
key.instance(Namespace.init("f:g").get) == Key.init("a:b/c/d:g").get
|
||||
Key.init("a:b").get.instance(Namespace.init(":c").get) == Key.init("a:c").get
|
||||
Key.init(":b").get.instance(Namespace.init(":c").get) == Key.init("b:c").get
|
||||
Key.init(":b").get.instance(key) == Key.init("b:e").get
|
||||
Namespace.init("a:b").get.instance(Namespace.init("c").get) == Key.init("a:c").get
|
||||
Namespace.init(":b").get.instance(Namespace.init("c").get) == Key.init("b:c").get
|
||||
Namespace.init("a:b").get.instance(key) == Key.init("a:e").get
|
||||
Namespace.init(":b").get.instance(key) == Key.init("b:e").get
|
||||
Key.init(":b").get.instance("").isErr
|
||||
Key.init(":b").get.instance(":").isErr
|
||||
Key.init(":b").get.instance("/").isErr
|
||||
Key.init(":b").get.instance("//").isErr
|
||||
Key.init(":b").get.instance("///").isErr
|
||||
Key.init(":b").get.instance("a").get == Key.init("b:a").get
|
||||
Key.init(":b").get.instance(":b").get == Key.init("b:b").get
|
||||
Key.init(":b").get.instance("a:b").get == Key.init("b:b").get
|
||||
Key.init(":b").get.instance("/a:b/c/d:e").get == Key.init("b:e").get
|
||||
Key.init("a:b").get.instance("a").get == Key.init("a:a").get
|
||||
Key.init("a:b").get.instance(":b").get == Key.init("a:b").get
|
||||
Key.init("a:b").get.instance("a:b").get == Key.init("a:b").get
|
||||
Key.init("a:b").get.instance("/a:b/c/d:e").get == Key.init("a:e").get
|
||||
Key.init(":b").tryGet().parent.isFailure
|
||||
Key.init(":b").tryGet().parent.isFailure
|
||||
key.parent.tryGet() == Key.init("a:b/c").tryGet()
|
||||
key.parent.?parent.tryGet() == Key.init("a:b").tryGet()
|
||||
key.parent.?parent.?parent.isFailure
|
||||
|
||||
check:
|
||||
Key.init(":b").get.isTopLevel
|
||||
not Key.init(":b/c").get.isTopLevel
|
||||
key.parent.?path.tryGet() == Key.init("a:b").tryGet()
|
||||
key.path.tryGet() == Key.init("a:b/c/d").tryGet()
|
||||
Key.init("a:b/c").?path.tryGet() == Key.init("a:b").tryGet()
|
||||
Key.init("a:b/c/d:e").?path.tryGet() == Key.init("a:b/c/d").tryGet()
|
||||
|
||||
check:
|
||||
Key.init(":b").get.parent.isErr
|
||||
Key.init(":b").parent.isErr
|
||||
key.parent.get == Key.init("a:b/c").get
|
||||
key.parent.parent.get == Key.init("a:b").get
|
||||
key.parent.parent.parent.isErr
|
||||
check: key.child(Namespace.init("f:g").tryGet()) == Key.init("a:b/c/d:e/f:g").tryGet()
|
||||
|
||||
check:
|
||||
key.parent.get.path.get == Key.init("a:b").get
|
||||
key.path.get == Key.init("a:b/c/d").get
|
||||
Key.init("a:b/c").path.get == Key.init("a:b").get
|
||||
Key.init("a:b/c/d:e").path.get == Key.init("a:b/c/d").get
|
||||
|
||||
check: key.child(Namespace.init("f:g").get) == Key.init("a:b/c/d:e/f:g").get
|
||||
|
||||
check: key / Namespace.init("f:g").get == Key.init("a:b/c/d:e/f:g").get
|
||||
check: key / Namespace.init("f:g").tryGet() == Key.init("a:b/c/d:e/f:g").tryGet()
|
||||
|
||||
var
|
||||
emptyNss: seq[Namespace]
|
||||
|
||||
check:
|
||||
key.child(emptyNss) == key
|
||||
key.child(Namespace.init("f:g").get, Namespace.init("h:i").get) ==
|
||||
Key.init("a:b/c/d:e/f:g/h:i").get
|
||||
key.child(Namespace.init("f:g").tryGet(), Namespace.init("h:i").tryGet()) ==
|
||||
Key.init("a:b/c/d:e/f:g/h:i").tryGet()
|
||||
|
||||
check:
|
||||
key.child(Key.init("f:g").get) == Key.init("a:b/c/d:e/f:g").get
|
||||
key / Key.init("f:g").get == Key.init("a:b/c/d:e/f:g").get
|
||||
key.child(Key.init("f:g").tryGet()) == Key.init("a:b/c/d:e/f:g").tryGet()
|
||||
key / Key.init("f:g").tryGet() == Key.init("a:b/c/d:e/f:g").tryGet()
|
||||
|
||||
var
|
||||
emptyKeys: seq[Key]
|
||||
|
||||
check:
|
||||
key.child(emptyKeys) == key
|
||||
key.child(Key.init("f:g").get, Key.init("h:i").get) ==
|
||||
Key.init("a:b/c/d:e/f:g/h:i").get
|
||||
key.child(Key.init("f:g").tryGet(), Key.init("h:i").tryGet()) ==
|
||||
Key.init("a:b/c/d:e/f:g/h:i").tryGet()
|
||||
|
||||
check:
|
||||
key.child("f:g", ":::").isErr
|
||||
key.child("f:g", "h:i").get == Key.init("a:b/c/d:e/f:g/h:i").get
|
||||
key.child("").get == key
|
||||
key.child("", "", "").get == key
|
||||
key.child("f:g", ":::").isFailure
|
||||
key.child("f:g", "h:i").tryGet() == Key.init("a:b/c/d:e/f:g/h:i").tryGet()
|
||||
key.child("").tryGet() == key
|
||||
key.child("", "", "").tryGet() == key
|
||||
|
||||
check:
|
||||
(key / "").get == key
|
||||
(key / "f:g").get == Key.init("a:b/c/d:e/f:g").get
|
||||
(key / "").tryGet() == key
|
||||
(key / "f:g").tryGet() == Key.init("a:b/c/d:e/f:g").tryGet()
|
||||
|
||||
check:
|
||||
not key.isAncestorOf(Key.init("f:g").get)
|
||||
key.isAncestorOf(key / Key.init("f:g").get)
|
||||
not key.isAncestorOf(Key.init("f:g").tryGet())
|
||||
key.isAncestorOf(key / Key.init("f:g").tryGet())
|
||||
|
||||
check:
|
||||
key.isDescendantOf(key.parent.get)
|
||||
not Key.init("f:g").get.isDescendantOf(key.parent.get)
|
||||
key.isDescendantOf(key.parent.tryGet())
|
||||
not Key.init("f:g").tryGet().isDescendantOf(key.parent.tryGet())
|
||||
|
||||
test "serialization":
|
||||
let
|
||||
idStr = "/a:b/c/d:e"
|
||||
key = Key.init(idStr).get
|
||||
key = Key.init(idStr).tryGet()
|
||||
|
||||
check:
|
||||
key.id == idStr
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user