Skip to content

Commit c4bdde9

Browse files
authored
move chronos integration to its own module (#128)
No reason std/net should depend on chronos - to provide backwards-compatibility, the chronos writers are re-exported when json_serialization is available.
1 parent e076cb9 commit c4bdde9

File tree

11 files changed

+132
-90
lines changed

11 files changed

+132
-90
lines changed

docs/examples/getstarted1.nim

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,19 @@ import json_serialization
66
type JsonRpcId = distinct JsonString
77

88
proc readValue*(
9-
r: var JsonReader, val: var JsonRpcId
9+
r: var JsonReader, value: var JsonRpcId
1010
) {.raises: [IOError, JsonReaderError].} =
1111
let tok = r.tokKind
1212
case tok
1313
of JsonValueKind.Number, JsonValueKind.String, JsonValueKind.Null:
1414
# Keep the original value without further processing
15-
val = JsonRpcId(r.parseAsString())
15+
value = JsonRpcId(r.parseAsString())
1616
else:
1717
r.raiseUnexpectedValue("Invalid RequestId, got " & $tok)
1818

19-
proc writeValue*(w: var JsonWriter, val: JsonRpcId) {.raises: [IOError].} =
20-
w.writeValue(JsonString(val)) # Preserve the original content
19+
proc writeValue*(w: var JsonWriter, value: JsonRpcId) {.raises: [IOError].} =
20+
w.writeValue(JsonString(value)) # Preserve the original content
21+
2122
# ANCHOR_END: Custom
2223

2324
type Request = object

docs/examples/getstarted2.nim

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,18 @@ createJsonFlavor JrpcSys,
1717
type JsonRpcId = distinct JsonString
1818

1919
proc readValue*(
20-
r: var JsonReader[JrpcSys], val: var JsonRpcId
20+
r: var JsonReader[JrpcSys], value: var JsonRpcId
2121
) {.raises: [IOError, JsonReaderError].} =
2222
let tok = r.tokKind
2323
case tok
2424
of JsonValueKind.Number, JsonValueKind.String, JsonValueKind.Null:
2525
# Keep the original value without further processing
26-
val = JsonRpcId(r.parseAsString())
26+
value = JsonRpcId(r.parseAsString())
2727
else:
2828
r.raiseUnexpectedValue("Invalid RequestId, got " & $tok)
2929

30-
proc writeValue*(w: var JsonWriter[JrpcSys], val: JsonRpcId) {.raises: [IOError].} =
31-
w.writeValue(JsonString(val)) # Preserve the original content
30+
proc writeValue*(w: var JsonWriter[JrpcSys], value: JsonRpcId) {.raises: [IOError].} =
31+
w.writeValue(JsonString(value)) # Preserve the original content
3232
# ANCHOR_END: Custom
3333

3434
# ANCHOR: Request

docs/src/reference.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,12 @@ Parsing and writing can be customized by providing overloads for the `readValue`
133133

134134
```nim
135135
# Custom serializers for MyType should match the following signatures
136-
proc readValue*(r: var JsonReader, v: var MyType) {.raises: [IOError, SerializationError].}
137-
proc writeValue*(w: var JsonWriter, v: MyType) {.raises: [IOError].}
136+
proc readValue*(r: var JsonReader, value: var MyType) {.raises: [IOError, SerializationError].}
137+
proc writeValue*(w: var JsonWriter, value: MyType) {.raises: [IOError].}
138138
139139
# When flavors are used, add the flavor as well
140-
proc readValue*(r: var JsonReader[MyFlavor], v: var MyType) {.raises: [IOError, SerializationError].}
141-
proc writeValue*(w: var JsonWriter[MyFlavor], v: MyType) {.raises: [IOError].}
140+
proc readValue*(r: var JsonReader[MyFlavor], value: var MyType) {.raises: [IOError, SerializationError].}
141+
proc writeValue*(w: var JsonWriter[MyFlavor], value: MyType) {.raises: [IOError].}
142142
```
143143

144144
The JsonReader provides access to the JSON token stream coming out of the lexer. While the token stream can be accessed directly, there are several helpers that make it easier to correctly parse common JSON shapes.
@@ -148,9 +148,9 @@ The JsonReader provides access to the JSON token stream coming out of the lexer.
148148
Decode objects using the `parseObject` template. To parse values, use helper functions or `readValue`. The `readObject` and `readObjectFields` iterators are also useful for custom object parsers.
149149

150150
```nim
151-
proc readValue*(r: var JsonReader, table: var Table[string, int]) =
151+
proc readValue*(r: var JsonReader, value: var Table[string, int]) =
152152
parseObject(r, key):
153-
table[key] = r.parseInt(int)
153+
value[key] = r.parseInt(int)
154154
```
155155

156156
### Sets and List-like Types

json_serialization/pkg/chronos.nim

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# json-serialization
2+
# Copyright (c) 2019-2025 Status Research & Development GmbH
3+
# Licensed under either of
4+
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
5+
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
6+
# at your option.
7+
# This file may not be copied, modified, or distributed except according to
8+
# those terms.
9+
10+
{.push raises: [], gcsafe.}
11+
12+
import ../../json_serialization/[reader, writer], ../std/net
13+
14+
from chronos/transports/common import
15+
TransportAddress, TransportAddressError, initTAddress, `$`
16+
17+
export TransportAddress, net
18+
19+
proc writeValue*(w: var JsonWriter, value: TransportAddress) {.raises: [IOError].} =
20+
w.writeValue($value)
21+
22+
proc readValue*(
23+
r: var JsonReader, value: var TransportAddress
24+
) {.raises: [IOError, SerializationError].} =
25+
let s = r.readValue(string)
26+
try:
27+
value = initTAddress(s)
28+
except TransportAddressError as exc:
29+
r.raiseUnexpectedValue("Cannot parse TransportAddress: " & exc.msg)

json_serialization/pkg/results.nim

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,33 +9,31 @@
99

1010
{.push raises: [], gcsafe.}
1111

12-
import
13-
pkg/results, ../../json_serialization/[reader, writer, lexer]
12+
import pkg/results, ../../json_serialization/[reader, writer, lexer]
1413

15-
export
16-
results
14+
export results
1715

18-
template shouldWriteObjectField*[T](field: Result[T, void]): bool =
16+
template shouldWriteObjectField*[T](field: Opt[T]): bool =
1917
field.isOk
2018

21-
proc writeValue*[T](
22-
writer: var JsonWriter, value: Result[T, void]) {.raises: [IOError].} =
19+
proc writeValue*[T](w: var JsonWriter, value: Opt[T]) {.raises: [IOError].} =
2320
mixin writeValue
2421

2522
if value.isOk:
26-
writer.writeValue value.get
23+
w.writeValue(value.get)
2724
else:
28-
writer.writeValue JsonString("null")
25+
w.writeValue JsonString("null")
2926

30-
proc readValue*[T](reader: var JsonReader, value: var Result[T, void]) {.
31-
raises: [IOError, SerializationError].} =
27+
proc readValue*[T](
28+
r: var JsonReader, value: var Opt[T]
29+
) {.raises: [IOError, SerializationError].} =
3230
mixin readValue
3331

34-
if reader.tokKind == JsonValueKind.Null:
32+
if r.tokKind == JsonValueKind.Null:
3533
reset value
36-
reader.parseNull()
34+
r.parseNull()
3735
else:
38-
value.ok reader.readValue(T)
36+
value.ok r.readValue(T)
3937

40-
func isFieldExpected*[T, E](_: type[Result[T, E]]): bool {.compileTime.} =
38+
func isFieldExpected*[T](_: type[Opt[T]]): bool {.compileTime.} =
4139
false

json_serialization/std/net.nim

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# json-serialization
1+
# json_serialization
22
# Copyright (c) 2019-2025 Status Research & Development GmbH
33
# Licensed under either of
44
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
@@ -9,35 +9,26 @@
99

1010
{.push raises: [], gcsafe.}
1111

12-
import
13-
std/[net, strutils],
14-
chronos/transports/common,
15-
../../json_serialization
12+
import ../../json_serialization, std/net
13+
export net
1614

17-
export
18-
net, common
15+
when compiles((; import chronos/transports/common)):
16+
# Backwards-compat with json_ser <= 0.4.2
17+
import ../pkg/chronos as jschronos
18+
export jschronos
1919

20-
proc writeValue*(
21-
writer: var JsonWriter, value: IpAddress) {.raises: [IOError].} =
22-
writeValue(writer, $value)
20+
proc writeValue*(w: var JsonWriter, value: IpAddress) {.raises: [IOError].} =
21+
w.writeValue($value)
2322

24-
proc readValue*(reader: var JsonReader, value: var IpAddress) =
25-
let s = reader.readValue(string)
23+
proc readValue*(
24+
r: var JsonReader, value: var IpAddress
25+
) {.raises: [IOError, SerializationError].} =
26+
let s = r.readValue(string)
2627
try:
27-
value = parseIpAddress s
28-
except CatchableError:
29-
raiseUnexpectedValue(reader, "Invalid IP address")
28+
value = parseIpAddress(s)
29+
except ValueError as exc:
30+
r.raiseUnexpectedValue(exc.msg)
3031

31-
proc writeValue*(
32-
writer: var JsonWriter, value: Port) {.raises: [IOError].} =
33-
writeValue(writer, uint16 value)
32+
Port.serializesAsBase(Json)
3433

35-
proc readValue*(reader: var JsonReader, value: var Port) =
36-
value = Port reader.readValue(uint16)
37-
38-
proc writeValue*(
39-
writer: var JsonWriter, value: AddressFamily) {.raises: [IOError].} =
40-
writeValue(writer, $value)
41-
42-
proc readValue*(reader: var JsonReader, value: var AddressFamily) =
43-
value = parseEnum[AddressFamily](reader.readValue(string))
34+
{.pop.}

json_serialization/std/options.nim

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,21 @@ export options
1515
template shouldWriteObjectField*(field: Option): bool =
1616
field.isSome
1717

18-
proc writeValue*(writer: var JsonWriter, value: Option) {.raises: [IOError].} =
18+
proc writeValue*(w: var JsonWriter, value: Option) {.raises: [IOError].} =
1919
mixin writeValue
2020

2121
if value.isSome:
22-
writer.writeValue value.get
22+
w.writeValue value.get
2323
else:
24-
writer.writeValue JsonString("null")
24+
w.writeValue JsonString("null")
2525

26-
proc readValue*[T](reader: var JsonReader, value: var Option[T]) {.
27-
raises: [IOError, SerializationError].} =
26+
proc readValue*[T](
27+
r: var JsonReader, value: var Option[T]
28+
) {.raises: [IOError, SerializationError].} =
2829
mixin readValue
2930

30-
if reader.tokKind == JsonValueKind.Null:
31+
if r.tokKind == JsonValueKind.Null:
3132
reset value
32-
reader.parseNull()
33+
r.parseNull()
3334
else:
34-
value = some reader.readValue(T)
35+
value = some r.readValue(T)

json_serialization/std/sets.nim

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@
1212
import stew/shims/sets, ../../json_serialization/[reader, writer, lexer]
1313
export sets
1414

15-
type
16-
SetType = OrderedSet | HashSet | set
15+
type SetType = OrderedSet | HashSet | set
1716

18-
proc writeValue*(writer: var JsonWriter, value: SetType) {.raises: [IOError].} =
19-
writer.writeIterable value
17+
proc writeValue*(w: var JsonWriter, value: SetType) {.raises: [IOError].} =
18+
w.writeIterable value
2019

21-
proc readValue*(reader: var JsonReader, value: var SetType) {.
22-
raises: [IOError, SerializationError].} =
20+
proc readValue*(
21+
r: var JsonReader, value: var SetType
22+
) {.raises: [IOError, SerializationError].} =
2323
type ElemType = type(value.items)
2424
value = init SetType
25-
for elem in readArray(reader, ElemType):
25+
for elem in r.readArray(ElemType):
2626
value.incl elem

json_serialization/std/tables.nim

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,19 @@
99

1010
{.push raises: [], gcsafe.}
1111

12-
import
13-
std/strutils,
14-
stew/shims/tables,
15-
../../json_serialization/[reader, writer, lexer]
12+
import std/strutils, stew/shims/tables, ../../json_serialization/[reader, writer, lexer]
1613

1714
export tables
1815

19-
type
20-
TableType = OrderedTable | Table
16+
type TableType = OrderedTable | Table
2117

22-
proc writeValue*(
23-
writer: var JsonWriter, value: TableType) {.raises: [IOError].} =
24-
writer.beginRecord()
25-
for key, val in value:
26-
writer.writeField $key, val
27-
writer.endRecord()
18+
proc writeValue*(w: var JsonWriter, value: TableType) {.raises: [IOError].} =
19+
w.writeObject:
20+
for key, val in value:
21+
w.writeField $key, val
2822

2923
template to*(a: string, b: typed): untyped =
30-
{.error: "doesnt support keys with type " & $type(b) .}
24+
{.error: "doesnt support keys with type " & $type(b).}
3125

3226
template to*(a: string, b: type int): int =
3327
parseInt(a)
@@ -38,13 +32,14 @@ template to*(a: string, b: type float): float =
3832
template to*(a: string, b: type string): string =
3933
a
4034

41-
proc readValue*(reader: var JsonReader, value: var TableType) {.
42-
raises: [IOError, SerializationError].} =
35+
proc readValue*(
36+
r: var JsonReader, value: var TableType
37+
) {.raises: [IOError, SerializationError].} =
4338
try:
4439
type KeyType = type(value.keys)
4540
type ValueType = type(value.values)
4641
value = init TableType
47-
for key, val in readObject(reader, string, ValueType):
42+
for key, val in r.readObject(string, ValueType):
4843
value[to(key, KeyType)] = val
4944
except ValueError as ex:
50-
reader.raiseUnexpectedValue("TableType: " & ex.msg)
45+
r.raiseUnexpectedValue("TableType: " & ex.msg)

json_serialization/std/uri.nim

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# json_serialization
2+
# Copyright (c) 2025 Status Research & Development GmbH
3+
# Licensed under either of
4+
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
5+
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
6+
# at your option.
7+
# This file may not be copied, modified, or distributed except according to
8+
# those terms.
9+
10+
{.push raises: [], gcsafe.}
11+
12+
import ../../json_serialization, std/uri
13+
export uri
14+
15+
proc writeValue*(w: var JsonWriter, value: Uri) {.raises: [IOError].} =
16+
w.writeValue($value)
17+
18+
proc readValue*(
19+
r: var JsonReader, value: var Uri
20+
) {.raises: [IOError, SerializationError].} =
21+
let s = r.readValue(string)
22+
try:
23+
value = parseUri(s)
24+
except ValueError as exc:
25+
r.raiseUnexpectedValue(exc.msg)
26+
27+
{.pop.}

0 commit comments

Comments
 (0)