Types
IdxCostMap = Table[(int, int), int]
- Source Edit
SexpMismatch = object path*: SexpPath ## Full path for the mismatched case kind*: SexpMismatchKind of smMissingKey: key*: string ## Key missing in the input data of smDifferentLiteral, smKindMismatch, smArrayLen, smDifferentSymbol: expected*, found*: SexpNode ## 'expected X' but 'found Y' error messages arraydiff*: tuple[target, input: seq[int]] ## For comparison of the ## lists keys - indices of the non-field elements.
- Single S-expression mismatch Source Edit
SexpMismatchKind = enum smMissingKey, ## Input data has no `:key` that was present in expected smDifferentLiteral, ## Target has different literal values from the expected smDifferentSymbol, ## Target has different symbol at position smArrayLen, ## Mismatched array len smKindMismatch ## Different kinds of nodes - expected string but found ## int for example
- Possible kinds of the mismatches Source Edit
Procs
proc describeDiff(diff: seq[SexpMismatch]; conf: DiffFormatConf): ColText {. ...raises: [ValueError, Exception], tags: [RootEffect].}
- Generate colortext description of the S-expression mismatch diff Source Edit
proc diff(target, input: SexpNode): seq[SexpMismatch] {....raises: [KeyError], tags: [].}
-
Recursively iterate over target and input trees, find all mismatches.
Comparison rules:
- _ in expected matches to anything
- Excess fields in input are discarded
- Missing fields in target are treated as errors
- List with keys are compared in two passes - only :key to :key between two lists - in unordered manner. Then all remaining elements are processed in the order of their appearance.
- Literals and kinds are compared directly with ==
func mismatch(path: SexpPath; key: string): SexpMismatch {....raises: [], tags: [].}
- Create missing key mismatch Source Edit
func sdiffPart(index: int): SexpPathPart {....raises: [], tags: [].}
- Create single S-expression index part Source Edit
func sdiffPart(key: string): SexpPathPart {....raises: [], tags: [].}
- Create single S-expression key path part Source Edit
proc stableMatch(lhsLen, rhsLen: int; weight: proc (a, b: int): int; order: SortOrder = SortOrder.Ascending): tuple[ lhsIgnore, rhsIgnore: seq[int], map: seq[tuple[pair: (int, int), cost: int]]] {. ...raises: [KeyError, Exception], tags: [RootEffect].}
-
Do a weighted matching of the items in lhs and rhs sequences using weight function. Return most cost-effective matching elements.
- lhsLen and rhsLen lists number of the elements in each input sequence
- weight - comparison proc that returns match score between two items as position a and b.
- order - comparison ordering. If it is Ascending higher matching cost is consdered better and replaces previous mappings. If Descending prefer lower matching cost instead
For generating mapping of two sequences make weight function a closure and let it retrieve values as needed.
Source Edit