Skip to content

Commit

Permalink
Add some enhancements to jsonutils.nim (nim-lang#15133)
Browse files Browse the repository at this point in the history
* Add some enhancements to `jsonutils.nim`

* Use `jsonutils.nim` hookable API to add a possibility to deserialize
  JSON arrays directly to `HashSet` and `OrderedSet` types and
  respectively to serialize those types to JSON arrays.

* Also add a possibility to deserialize JSON `null` objects to Nim
  option objects and respectively to serialize Nim option object to JSON
  object if some or to JSON `null` object if none.

* Move serialization/deserialization functionality for `Table` and
  `OrderedTable` types from `jsonutils.nim` to `tables.nim` via the
  hookable API.

* Add object `jsonutils.Joptions` and parameter from its type to
  `jsonutils.fromJson` procedure to control whether to allow
  deserializing JSON objects to Nim objects when the JSON has some
  extra or missing keys.

* Add unit tests for the added functionalities to `tjsonutils.nim`.

* improve fromJsonFields

* Add changelog entry for the jsonutils enhancements

* Add TODO in `jsonutils.nim`

* Added an entry to "Future directions" section in `jsonutils.nim` as
  suggestion for future support of serialization and de-serialization of
  nested variant objects.

* Added currently disabled test case in `tjsonutils.nim` for testing
  serialization and de-serialization of nested variant objects.

* Move JSON hooks to `jsonutils.nim`

Move `fromJsonHook` and `toJsonHook` procedures for different types to
`jsonutils.nim` module to avoid a dependency of collections modules to
the `json.nim` module.

The hooks are removed from the following modules:

  * `tables.nim`

  * `sets.nim`

  * `options.nim`

  * `strtabs.nim`

* Add some tests about `StringTableRef`

Add tests for `StringTableRef`'s `fromJsonHook` and `toJsonHook` to
`tjsonutils.nim`.

* Disable a warning in `jsonutils.nim`

Mark `fun` template in `jsonutils` module with `{.used.}` pragma in
order to disable `[XDeclaredButNotUsed]` hint. The template is actually
used by the `initCaseObject` macro in the same module.

Co-authored-by: Timothee Cour <timothee.cour2@gmail.com>
  • Loading branch information
2 people authored and mildred committed Jan 11, 2021
1 parent 0c7535e commit 49fed86
Show file tree
Hide file tree
Showing 7 changed files with 447 additions and 59 deletions.
14 changes: 14 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@

## Standard library additions and changes

- Added some enhancements to `std/jsonutils` module.
* Added a possibility to deserialize JSON arrays directly to `HashSet` and
`OrderedSet` types and respectively to serialize those types to JSON arrays
via `jsonutils.fromJson` and `jsonutils.toJson` procedures.
* Added a possibility to deserialize JSON `null` objects to Nim option objects
and respectively to serialize Nim option object to JSON object if `isSome`
or to JSON null object if `isNone` via `jsonutils.fromJson` and
`jsonutils.toJson` procedures.
* Added `Joptions` parameter to `jsonutils.fromJson` procedure currently
containing two boolean options `allowExtraKeys` and `allowMissingKeys`.
- If `allowExtraKeys` is `true` Nim's object to which the JSON is parsed is
not required to have a field for every JSON key.
- If `allowMissingKeys` is `true` Nim's object to which JSON is parsed is
allowed to have fields without corresponding JSON keys.
- Added `bindParams`, `bindParam` to `db_sqlite` for binding parameters into a `SqlPrepared` statement.
- Add `tryInsert`,`insert` procs to `db_*` libs accept primary key column name.
- Added `xmltree.newVerbatimText` support create `style`'s,`script`'s text.
Expand Down
4 changes: 2 additions & 2 deletions lib/pure/collections/sets.nim
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ type
## <#initOrderedSet,int>`_ before calling other procs on it.
data: OrderedKeyValuePairSeq[A]
counter, first, last: int
SomeSet*[A] = HashSet[A] | OrderedSet[A]
## Type union representing `HashSet` or `OrderedSet`.

const
defaultInitialSize* = 64
Expand Down Expand Up @@ -907,8 +909,6 @@ iterator pairs*[A](s: OrderedSet[A]): tuple[a: int, b: A] =
forAllOrderedPairs:
yield (idx, s.data[h].key)



# -----------------------------------------------------------------------


Expand Down
4 changes: 0 additions & 4 deletions lib/pure/collections/tables.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1750,10 +1750,6 @@ iterator mvalues*[A, B](t: var OrderedTable[A, B]): var B =
yield t.data[h].val
assert(len(t) == L, "the length of the table changed while iterating over it")





# ---------------------------------------------------------------------------
# --------------------------- OrderedTableRef -------------------------------
# ---------------------------------------------------------------------------
Expand Down
1 change: 0 additions & 1 deletion lib/pure/options.nim
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,6 @@ proc unsafeGet*[T](self: Option[T]): lent T {.inline.}=
assert self.isSome
result = self.val


when isMainModule:
import unittest, sequtils

Expand Down
20 changes: 1 addition & 19 deletions lib/pure/strtabs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ const
growthFactor = 2
startSize = 64

proc mode*(t: StringTableRef): StringTableMode {.inline.} = t.mode

iterator pairs*(t: StringTableRef): tuple[key, value: string] =
## Iterates over every `(key, value)` pair in the table `t`.
Expand Down Expand Up @@ -422,25 +423,6 @@ proc `%`*(f: string, t: StringTableRef, flags: set[FormatFlag] = {}): string {.
add(result, f[i])
inc(i)

since (1,3,5):
proc fromJsonHook*[T](a: var StringTableRef, b: T) =
## for json.fromJson
mixin jsonTo
var mode = jsonTo(b["mode"], StringTableMode)
a = newStringTable(mode)
let b2 = b["table"]
for k,v in b2: a[k] = jsonTo(v, string)

proc toJsonHook*[](a: StringTableRef): auto =
## for json.toJson
mixin newJObject
mixin toJson
result = newJObject()
result["mode"] = toJson($a.mode)
let t = newJObject()
for k,v in a: t[k] = toJson(v)
result["table"] = t

when isMainModule:
var x = {"k": "v", "11": "22", "565": "67"}.newStringTable
assert x["k"] == "v"
Expand Down
Loading

0 comments on commit 49fed86

Please sign in to comment.