2018-11-11 11:40:19 +00:00
|
|
|
import
|
2019-03-11 09:34:04 +00:00
|
|
|
faststreams, serialization/[object_serialization, errors]
|
2018-11-11 11:40:19 +00:00
|
|
|
|
|
|
|
export
|
2019-03-11 09:34:04 +00:00
|
|
|
faststreams, object_serialization, errors
|
2018-11-10 00:14:43 +00:00
|
|
|
|
2018-12-17 23:00:00 +00:00
|
|
|
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) =
|
2018-11-29 01:33:45 +00:00
|
|
|
mixin writeValue, getOutput
|
2018-12-17 23:00:00 +00:00
|
|
|
writer.writeValue value
|
|
|
|
|
|
|
|
template encode*(Format: type, value: auto, params: varargs[untyped]): auto =
|
2018-12-28 01:01:24 +00:00
|
|
|
mixin init, WriterType, PreferedOutputType
|
2019-03-11 09:34:04 +00:00
|
|
|
var s = init OutputStream
|
2018-12-17 23:00:00 +00:00
|
|
|
|
|
|
|
# TODO:
|
|
|
|
# Remove this when statement once the following bug is fixed:
|
|
|
|
# https://github.com/nim-lang/Nim/issues/9996
|
|
|
|
when astToStr(params) != "":
|
2019-03-11 09:34:04 +00:00
|
|
|
var writer = init(WriterType(Format), s, params)
|
2018-12-17 23:00:00 +00:00
|
|
|
else:
|
2019-03-11 09:34:04 +00:00
|
|
|
var writer = init(WriterType(Format), s)
|
2018-12-17 23:00:00 +00:00
|
|
|
|
|
|
|
encodeImpl(writer, value)
|
2019-03-11 09:34:04 +00:00
|
|
|
s.getOutput PreferedOutputType(Format)
|
2018-12-17 23:00:00 +00:00
|
|
|
|
|
|
|
proc readValue*(reader: var auto, T: type): T =
|
|
|
|
mixin readValue
|
|
|
|
reader.readValue(result)
|
|
|
|
|
|
|
|
template decode*(Format: distinct type,
|
2019-03-11 09:34:04 +00:00
|
|
|
input: string,
|
2019-01-21 17:39:18 +00:00
|
|
|
RecordType: distinct type,
|
|
|
|
params: varargs[untyped]): auto =
|
2019-03-11 09:34:04 +00:00
|
|
|
# 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]`
|
2019-01-21 17:39:18 +00:00
|
|
|
mixin init, ReaderType
|
2018-12-17 23:00:00 +00:00
|
|
|
var stream = memoryStream(input)
|
2019-01-21 17:39:18 +00:00
|
|
|
|
|
|
|
# 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)
|
2018-12-17 23:00:00 +00:00
|
|
|
|
|
|
|
template loadFile*(Format: distinct type,
|
|
|
|
filename: string,
|
2019-01-21 17:39:18 +00:00
|
|
|
RecordType: distinct type,
|
|
|
|
params: varargs[untyped]): auto =
|
|
|
|
mixin init, ReaderType
|
2018-12-17 23:00:00 +00:00
|
|
|
var stream = openFile(filename)
|
2019-01-21 17:39:18 +00:00
|
|
|
|
|
|
|
# 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)
|
2018-12-17 23:00:00 +00:00
|
|
|
|
|
|
|
template loadFile*[RecordType](Format: type,
|
|
|
|
filename: string,
|
2019-01-21 17:39:18 +00:00
|
|
|
record: var RecordType,
|
|
|
|
params: varargs[untyped]) =
|
|
|
|
record = loadFile(Format, filename, RecordType, params)
|
2018-11-10 00:14:43 +00:00
|
|
|
|
2018-12-17 23:00:00 +00:00
|
|
|
template saveFile*(Format: type, filename: string, args: varargs[untyped]) =
|
2019-09-07 21:58:32 +00:00
|
|
|
when false:
|
|
|
|
# TODO use faststreams output stream
|
|
|
|
discard
|
|
|
|
else:
|
|
|
|
let bytes = Format.encode(args)
|
|
|
|
writeFile(filename, cast[string](bytes))
|
2018-11-29 01:33:45 +00:00
|
|
|
|
2019-03-13 21:20:27 +00:00
|
|
|
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)
|
|
|
|
|
2019-06-24 02:07:13 +00:00
|
|
|
template appendValue*(stream: OutputStreamVar, Format: type, value: auto) =
|
|
|
|
mixin WriterType, init, writeValue
|
|
|
|
var writer = init(WriterType(Format), stream)
|
|
|
|
writeValue writer, value
|
|
|
|
|