Add sort and cannonicalize
This commit is contained in:
parent
117aa19ef3
commit
a7a90097a8
|
@ -1,6 +1,6 @@
|
||||||
# Package
|
# Package
|
||||||
|
|
||||||
version = "20230607"
|
version = "20230611"
|
||||||
author = "Emery Hemingway"
|
author = "Emery Hemingway"
|
||||||
description = "data model and serialization format"
|
description = "data model and serialization format"
|
||||||
license = "Unlicense"
|
license = "Unlicense"
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
import std/[base64, endians, hashes, options, sets, sequtils, streams, tables, typetraits]
|
import std/[base64, endians, hashes, options, sets, sequtils, streams, tables, typetraits]
|
||||||
import ./preserves/private/macros
|
import ./preserves/private/macros
|
||||||
|
|
||||||
|
from std/algorithm import sort
|
||||||
from std/json import escapeJson, escapeJsonUnquoted
|
from std/json import escapeJson, escapeJsonUnquoted
|
||||||
from std/strutils import parseEnum
|
from std/strutils import parseEnum
|
||||||
import ./preserves/private/dot
|
import ./preserves/private/dot
|
||||||
|
@ -167,6 +168,30 @@ proc `<`*[A, B](x: Preserve[A]; y: Preserve[B]): bool =
|
||||||
when (not A is void) and (A is B):
|
when (not A is void) and (A is B):
|
||||||
result = x.embed < y.embed
|
result = x.embed < y.embed
|
||||||
|
|
||||||
|
proc cmp*[E](x, y: var Preserve[E]): int =
|
||||||
|
if x == y: 0
|
||||||
|
elif x < y: -1
|
||||||
|
else: 1
|
||||||
|
|
||||||
|
proc sort*[E](pr: var Preserve[E]) = sort(pr.sequence, cmp)
|
||||||
|
## Sort a Preserves array by total ordering.
|
||||||
|
|
||||||
|
proc cannonicalize*[E](pr: var Preserve[E]) {.gcsafe.} =
|
||||||
|
## Cannonicalize a compound Preserves value by total ordering.
|
||||||
|
case pr.kind
|
||||||
|
of pkSequence:
|
||||||
|
apply(pr.sequence, cannonicalize)
|
||||||
|
of pkSet:
|
||||||
|
apply(pr.set, cannonicalize)
|
||||||
|
sort(pr.set)
|
||||||
|
of pkDictionary:
|
||||||
|
apply(pr.dict) do (e: var DictEntry[E]):
|
||||||
|
cannonicalize(e.val)
|
||||||
|
sort(pr.dict) do (x, y: DictEntry[E]) -> int:
|
||||||
|
cmp(x.key, y.key)
|
||||||
|
else:
|
||||||
|
discard
|
||||||
|
|
||||||
proc hash*(pr: Preserve): Hash =
|
proc hash*(pr: Preserve): Hash =
|
||||||
## Produce a `Hash` of `pr` for use with a `HashSet` or `Table`.
|
## Produce a `Hash` of `pr` for use with a `HashSet` or `Table`.
|
||||||
var h = hash(pr.kind.int) !& hash(pr.embedded)
|
var h = hash(pr.kind.int) !& hash(pr.embedded)
|
||||||
|
|
Loading…
Reference in New Issue