Skip to content

Commit b53dd5d

Browse files
authored
writer: fix raises, allow Flavor in toJson (#113)
1 parent fd81708 commit b53dd5d

File tree

1 file changed

+21
-19
lines changed

1 file changed

+21
-19
lines changed

json_serialization/writer.nim

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
# json-serialization
2-
# Copyright (c) 2019-2023 Status Research & Development GmbH
2+
# Copyright (c) 2019-2025 Status Research & Development GmbH
33
# Licensed under either of
44
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
55
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
66
# at your option.
77
# This file may not be copied, modified, or distributed except according to
88
# those terms.
99

10+
{.push gcsafe, raises: [].}
11+
1012
import
1113
std/[json, typetraits],
1214
faststreams/[outputs, textio],
@@ -40,9 +42,7 @@ func init*(W: type JsonWriter, stream: OutputStream,
4042
nestingLevel: if pretty: 0 else: -1,
4143
state: RecordExpected)
4244

43-
proc beginRecord*(w: var JsonWriter, T: type)
44-
proc beginRecord*(w: var JsonWriter)
45-
proc writeValue*(w: var JsonWriter, value: auto) {.gcsafe, raises: [IOError].}
45+
proc writeValue*(w: var JsonWriter, value: auto) {.raises: [IOError].}
4646

4747
# If it's an optional field, test for it's value before write something.
4848
# If it's non optional field, the field is always written.
@@ -58,7 +58,7 @@ template indent =
5858
template `$`*(s: JsonString): string =
5959
string(s)
6060

61-
proc writeFieldName*(w: var JsonWriter, name: string) =
61+
proc writeFieldName*(w: var JsonWriter, name: string) {.raises: [IOError].} =
6262
# this is implemented as a separate proc in order to
6363
# keep the code bloat from `writeField` to a minimum
6464
doAssert w.state != RecordExpected
@@ -101,7 +101,7 @@ proc writeField*(
101101
template fieldWritten*(w: var JsonWriter) =
102102
w.state = AfterField
103103

104-
proc beginRecord*(w: var JsonWriter) =
104+
proc beginRecord*(w: var JsonWriter) {.raises: [IOError].} =
105105
doAssert w.state == RecordExpected
106106

107107
append '{'
@@ -110,11 +110,11 @@ proc beginRecord*(w: var JsonWriter) =
110110

111111
w.state = RecordStarted
112112

113-
proc beginRecord*(w: var JsonWriter, T: type) =
113+
proc beginRecord*(w: var JsonWriter, T: type) {.raises: [IOError].} =
114114
w.beginRecord()
115115
if w.hasTypeAnnotations: w.writeField("$type", typetraits.name(T))
116116

117-
proc endRecord*(w: var JsonWriter) =
117+
proc endRecord*(w: var JsonWriter) {.raises: [IOError].} =
118118
doAssert w.state != RecordExpected
119119

120120
if w.hasPrettyOutput:
@@ -128,7 +128,7 @@ template endRecordField*(w: var JsonWriter) =
128128
endRecord(w)
129129
w.state = AfterField
130130

131-
iterator stepwiseArrayCreation*[C](w: var JsonWriter, collection: C): auto =
131+
iterator stepwiseArrayCreation*[C](w: var JsonWriter, collection: C): auto {.raises: [IOError].} =
132132
append '['
133133

134134
if w.hasPrettyOutput:
@@ -155,12 +155,12 @@ iterator stepwiseArrayCreation*[C](w: var JsonWriter, collection: C): auto =
155155

156156
append ']'
157157

158-
proc writeIterable*(w: var JsonWriter, collection: auto) =
158+
proc writeIterable*(w: var JsonWriter, collection: auto) {.raises: [IOError].} =
159159
mixin writeValue
160160
for e in w.stepwiseArrayCreation(collection):
161161
w.writeValue(e)
162162

163-
proc writeArray*[T](w: var JsonWriter, elements: openArray[T]) =
163+
proc writeArray*[T](w: var JsonWriter, elements: openArray[T]) {.raises: [IOError].} =
164164
writeIterable(w, elements)
165165

166166
template writeObject*(w: var JsonWriter, T: type, body: untyped) =
@@ -193,8 +193,7 @@ template writeObjectField*[FieldType, RecordType](w: var JsonWriter,
193193
type R = type record
194194
w.writeFieldIMPL(FieldTag[R, fieldName], field, record)
195195

196-
proc writeRecordValue*(w: var JsonWriter, value: auto)
197-
{.gcsafe, raises: [IOError].} =
196+
proc writeRecordValue*(w: var JsonWriter, value: auto) {.raises: [IOError].} =
198197
mixin enumInstanceSerializedFields, writeObjectField
199198
mixin flavorOmitsOptionalFields, shouldWriteObjectField
200199

@@ -216,7 +215,7 @@ proc writeRecordValue*(w: var JsonWriter, value: auto)
216215
discard fieldName
217216
w.endRecord()
218217

219-
proc writeNumber*[F,T](w: var JsonWriter[F], value: JsonNumber[T]) =
218+
proc writeNumber*[F,T](w: var JsonWriter[F], value: JsonNumber[T]) {.raises: [IOError].} =
220219
if value.sign == JsonSign.Neg:
221220
append '-'
222221

@@ -246,7 +245,7 @@ proc writeNumber*[F,T](w: var JsonWriter[F], value: JsonNumber[T]) =
246245
else:
247246
append value.exponent
248247

249-
proc writeJsonValueRef*[F,T](w: var JsonWriter[F], value: JsonValueRef[T]) =
248+
proc writeJsonValueRef*[F,T](w: var JsonWriter[F], value: JsonValueRef[T]) {.raises: [IOError].} =
250249
if value.isNil:
251250
append "null"
252251
return
@@ -289,7 +288,7 @@ template writeValue*(w: var JsonWriter, value: enum) =
289288
type Flavor = type(w).Flavor
290289
writeEnumImpl(w, value, Flavor.flavorEnumRep())
291290

292-
proc writeValue*(w: var JsonWriter, value: auto) {.gcsafe, raises: [IOError].} =
291+
proc writeValue*(w: var JsonWriter, value: auto) {.raises: [IOError].} =
293292
mixin writeValue
294293

295294
when value is JsonNode:
@@ -391,13 +390,16 @@ proc writeValue*(w: var JsonWriter, value: auto) {.gcsafe, raises: [IOError].} =
391390
const typeName = typetraits.name(value.type)
392391
{.fatal: "Failed to convert to JSON an unsupported type: " & typeName.}
393392

394-
proc toJson*(v: auto, pretty = false, typeAnnotations = false): string =
393+
proc toJson*(v: auto, pretty = false, typeAnnotations = false, Flavor = DefaultFlavor): string {.raises: [].} =
395394
mixin writeValue
396395

397396
var
398397
s = memoryOutput()
399-
w = JsonWriter[DefaultFlavor].init(s, pretty, typeAnnotations)
400-
w.writeValue v
398+
w = JsonWriter[Flavor].init(s, pretty, typeAnnotations)
399+
try:
400+
w.writeValue v
401+
except IOError:
402+
raiseAssert "no exceptions from memoryOutput"
401403
s.getOutput(string)
402404

403405
template serializesAsTextInJson*(T: type[enum]) =

0 commit comments

Comments
 (0)