cleanup key

This commit is contained in:
Dmitriy Ryajov 2022-09-16 21:12:49 -06:00
parent 78653d9dd4
commit b150b2f922
No known key found for this signature in database
GPG Key ID: DA8C680CE7C657A4

View File

@ -28,7 +28,7 @@ const
# TODO: operator/s for combining string|Namespace,string|Namespace # TODO: operator/s for combining string|Namespace,string|Namespace
# TODO: lifting from ?![Namespace|Key] for various ops # TODO: lifting from ?![Namespace|Key] for various ops
proc init*( func init*(
T: type Namespace, T: type Namespace,
field, value: string): ?!T = field, value: string): ?!T =
@ -57,7 +57,7 @@ proc init*(
success T(field: field, value: value) success T(field: field, value: value)
proc init*(T: type Namespace, id: string): ?!T = func init*(T: type Namespace, id: string): ?!T =
if id.strip == "": if id.strip == "":
return failure "id string must not be all whitespace or empty" return failure "id string must not be all whitespace or empty"
@ -82,22 +82,25 @@ proc init*(T: type Namespace, id: string): ?!T =
T.init(field, value) T.init(field, value)
proc id*(self: Namespace): string = func id*(self: Namespace): string =
if self.field.len > 0: if self.field.len > 0:
self.field & delimiter & self.value self.field & delimiter & self.value
else: else:
self.value self.value
proc `$`*(namespace: Namespace): string = func hash*(namespace: Namespace): Hash =
hash(namespace.id)
func `$`*(namespace: Namespace): string =
"Namespace(" & namespace.id & ")" "Namespace(" & namespace.id & ")"
proc init*(T: type Key, namespaces: varargs[Namespace]): ?!T = func init*(T: type Key, namespaces: varargs[Namespace]): ?!T =
if namespaces.len == 0: if namespaces.len == 0:
failure "namespaces must contain at least one Namespace" failure "namespaces must contain at least one Namespace"
else: else:
success T(namespaces: @namespaces) success T(namespaces: @namespaces)
proc init*(T: type Key, namespaces: varargs[string]): ?!T = func init*(T: type Key, namespaces: varargs[string]): ?!T =
if namespaces.len == 0: if namespaces.len == 0:
failure "namespaces must contain at least one Namespace id string" failure "namespaces must contain at least one Namespace id string"
else: else:
@ -106,7 +109,7 @@ proc init*(T: type Key, namespaces: varargs[string]): ?!T =
?Namespace.init(it) ?Namespace.init(it)
)) ))
proc init*(T: type Key, id: string): ?!T = func init*(T: type Key, id: string): ?!T =
if id == "": if id == "":
return failure "id string must contain at least one Namespace" return failure "id string must contain at least one Namespace"
@ -122,7 +125,7 @@ proc init*(T: type Key, id: string): ?!T =
Key.init(nsStrs) Key.init(nsStrs)
proc list*(self: Key): seq[Namespace] = func list*(self: Key): seq[Namespace] =
self.namespaces self.namespaces
proc random*(T: type Key): string = proc random*(T: type Key): string =
@ -131,78 +134,91 @@ proc random*(T: type Key): string =
template `[]`*(key: Key, x: auto): auto = template `[]`*(key: Key, x: auto): auto =
key.namespaces[x] key.namespaces[x]
proc len*(self: Key): int = func len*(self: Key): int =
self.namespaces.len self.namespaces.len
iterator items*(key: Key): Namespace = iterator items*(key: Key): Namespace =
for k in key.namespaces: for k in key.namespaces:
yield k yield k
proc reversed*(self: Key): Key = func reversed*(self: Key): Key =
Key(namespaces: self.namespaces.reversed) Key(namespaces: self.namespaces.reversed)
proc reverse*(self: Key): Key = func reverse*(self: Key): Key =
self.reversed self.reversed
proc name*(self: Key): string = func name*(self: Key): string =
if self.len > 0: if self.len > 0:
return self[^1].value return self[^1].value
proc `type`*(self: Key): string = func `type`*(self: Key): string =
if self.len > 0: if self.len > 0:
return self[^1].field return self[^1].field
proc id*(self: Key): string = func id*(self: Key): string =
separator & self.namespaces.mapIt(it.id).join(separator) separator & self.namespaces.mapIt(it.id).join(separator)
proc isTopLevel*(self: Key): bool = func root*(self: Key): bool =
self.len == 1 self.len == 1
proc parent*(self: Key): ?!Key = func parent*(self: Key): ?!Key =
if self.isTopLevel: if self.root:
failure "key has no parent" failure "key has no parent"
else: else:
success Key(namespaces: self.namespaces[0..^2]) success Key(namespaces: self.namespaces[0..^2])
proc path*(self: Key): ?!Key = func path*(self: Key): ?!Key =
let let
parent = ? self.parent parent = ?self.parent
if self[^1].field == "": if self[^1].field == "":
return success parent return success parent
success Key(namespaces: parent.namespaces & @[Namespace(value: self[^1].field)]) let ns = parent.namespaces & @[Namespace(value: self[^1].field)]
success Key(namespaces: ns)
proc child*(self: Key, ns: Namespace): Key = func child*(self: Key, ns: Namespace): Key =
Key(namespaces: self.namespaces & @[ns]) Key(namespaces: self.namespaces & @[ns])
proc `/`*(self: Key, ns: Namespace): Key = func `/`*(self: Key, ns: Namespace): Key =
self.child(ns) self.child(ns)
proc child*(self: Key, namespaces: varargs[Namespace]): Key = func child*(self: Key, namespaces: varargs[Namespace]): Key =
Key(namespaces: self.namespaces & @namespaces) Key(namespaces: self.namespaces & @namespaces)
proc child*(self, key: Key): Key = func child*(self, key: Key): Key =
Key(namespaces: self.namespaces & key.namespaces) Key(namespaces: self.namespaces & key.namespaces)
proc `/`*(self, key: Key): Key = func `/`*(self, key: Key): Key =
self.child(key) self.child(key)
proc child*(self: Key, keys: varargs[Key]): Key = func child*(self: Key, keys: varargs[Key]): Key =
Key(namespaces: self.namespaces & concat(keys.mapIt(it.namespaces))) Key(namespaces: self.namespaces & concat(keys.mapIt(it.namespaces)))
proc child*(self: Key, ids: varargs[string]): ?!Key = func child*(self: Key, ids: varargs[string]): ?!Key =
success self.child(ids.filterIt(it != "").mapIt( ?Key.init(it) )) success self.child(ids.filterIt(it != "").mapIt( ?Key.init(it) ))
proc `/`*(self: Key, id: string): ?!Key = func relative*(self: Key, parent: Key): ?!Key =
## Get a key relative to parent from current key
##
if self.len < parent.len:
return failure "Not a parent of this key!"
Key.init(self.namespaces[parent.namespaces.high..self.namespaces.high])
func `/`*(self: Key, id: string): ?!Key =
self.child(id) self.child(id)
proc isAncestorOf*(self, other: Key): bool = func ancestor*(self, other: Key): bool =
if other.len <= self.len: false if other.len <= self.len: false
else: other.namespaces[0..<self.len] == self.namespaces else: other.namespaces[0..<self.len] == self.namespaces
proc isDescendantOf*(self, other: Key): bool = func descendant*(self, other: Key): bool =
other.isAncestorOf(self) other.ancestor(self)
proc `$`*(key: Key): string = func hash*(key: Key): Hash {.inline.} =
hash(key.id)
func `$`*(key: Key): string =
"Key(" & key.id & ")" "Key(" & key.id & ")"