-
Notifications
You must be signed in to change notification settings - Fork 8
/
serialization.nim
123 lines (100 loc) · 4.41 KB
/
serialization.nim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import
faststreams, serialization/[object_serialization, errors]
export
faststreams, object_serialization, errors
template serializationFormatImpl(Name: untyped,
Reader, Writer, PreferedOutput: distinct type,
mimeTypeName: static string = "") {.dirty.} =
# This indirection is required in order to be able to generate the
# `mimeType` accessor template. Without the indirection, the template
# mechanism of Nim will try to expand the `mimeType` param in the position
# of the `mimeType` template name which will result in error.
type Name* = object
template ReaderType*(T: type Name): type = Reader
template WriterType*(T: type Name): type = Writer
template PreferedOutputType*(T: type Name): type = PreferedOutput
template mimeType*(T: type Name): string = mimeTypeName
template serializationFormat*(Name: untyped,
Reader, Writer, PreferedOutput: distinct type,
mimeType: static string = "") =
serializationFormatImpl(Name, Reader, Writer, PreferedOutput, mimeType)
proc encodeImpl(writer: var auto, value: auto) =
mixin writeValue, getOutput
writer.writeValue value
template encode*(Format: type, value: auto, params: varargs[untyped]): auto =
mixin init, WriterType, PreferedOutputType
var s = init OutputStream
# TODO:
# Remove this when statement once the following bug is fixed:
# https://github.com/nim-lang/Nim/issues/9996
when astToStr(params) != "":
var writer = init(WriterType(Format), s, params)
else:
var writer = init(WriterType(Format), s)
encodeImpl(writer, value)
s.getOutput PreferedOutputType(Format)
proc readValue*(reader: var auto, T: type): T =
mixin readValue
reader.readValue(result)
template decode*(Format: distinct type,
input: string,
RecordType: distinct type,
params: varargs[untyped]): auto =
# TODO, this is dusplicated only due to a Nim bug:
# If `input` was `string|openarray[byte]`, it won't match `seq[byte]`
mixin init, ReaderType
var stream = memoryStream(input)
# TODO:
# Remove this when statement once the following bug is fixed:
# https://github.com/nim-lang/Nim/issues/9996
when astToStr(params) != "":
var reader = init(ReaderType(Format), stream, params)
else:
var reader = init(ReaderType(Format), stream)
reader.readValue(RecordType)
template decode*(Format: distinct type,
input: openarray[byte],
RecordType: distinct type,
params: varargs[untyped]): auto =
# TODO, this is dusplicated only due to a Nim bug:
# If `input` was `string|openarray[byte]`, it won't match `seq[byte]`
mixin init, ReaderType
var stream = memoryStream(input)
# TODO:
# Remove this when statement once the following bug is fixed:
# https://github.com/nim-lang/Nim/issues/9996
when astToStr(params) != "":
var reader = init(ReaderType(Format), stream, params)
else:
var reader = init(ReaderType(Format), stream)
reader.readValue(RecordType)
template loadFile*(Format: distinct type,
filename: string,
RecordType: distinct type,
params: varargs[untyped]): auto =
mixin init, ReaderType
var stream = openFile(filename)
# TODO:
# Remove this when statement once the following bug is fixed:
# https://github.com/nim-lang/Nim/issues/9996
when astToStr(params) != "":
var reader = init(ReaderType(Format), stream, params)
else:
var reader = init(ReaderType(Format), stream)
reader.readValue(RecordType)
template loadFile*[RecordType](Format: type,
filename: string,
record: var RecordType,
params: varargs[untyped]) =
record = loadFile(Format, filename, RecordType, params)
template saveFile*(Format: type, filename: string, args: varargs[untyped]) =
# TODO: This should use a proper output stream, instead of calling `encode`
writeFile(filename, Format.encode(args))
template borrowSerialization*(Alias: distinct type,
OriginalType: distinct type) {.dirty.} =
proc writeValue*[Writer](writer: var Writer, value: Alias) =
mixin writeValue
writeValue(writer, OriginalType value)
proc readValue*[Reader](reader: var Reader, value: var Alias) =
mixin readValue
value = Alias reader.readValue(OriginalType)