mirror of
https://github.com/waku-org/nwaku.git
synced 2025-01-16 09:55:07 +00:00
155 lines
5.6 KiB
Nim
155 lines
5.6 KiB
Nim
|
# toml-serialization
|
||
|
# Copyright (c) 2020 Status Research & Development GmbH
|
||
|
# Licensed and distributed under either of
|
||
|
# * MIT license: [LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT
|
||
|
# * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
||
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||
|
|
||
|
import
|
||
|
serialization, toml_serialization/[reader, writer, types],
|
||
|
toml_serialization/private/utils
|
||
|
|
||
|
export
|
||
|
serialization, reader, writer, types
|
||
|
|
||
|
serializationFormat Toml,
|
||
|
mimeType = "application/toml"
|
||
|
|
||
|
Toml.setReader TomlReader
|
||
|
Toml.setWriter TomlWriter, PreferredOutput = string
|
||
|
|
||
|
template supports*(_: type Toml, T: type): bool =
|
||
|
# The TOML format should support every type
|
||
|
# when not at top level ... :)
|
||
|
true
|
||
|
|
||
|
import
|
||
|
typetraits
|
||
|
|
||
|
type
|
||
|
# only objects | tuple | TomlValueRef allowed at top level
|
||
|
TomlSpecial* = TomlDateTime or TomlDate or TomlTime
|
||
|
TomlNotTopLevel* = SomeInteger or
|
||
|
seq or SomeFloat or string or
|
||
|
array or enum or bool or TomlSpecial
|
||
|
|
||
|
template tomlFatalImpl(fn, R: untyped) =
|
||
|
const typeName = typetraits.name(type R)
|
||
|
{.fatal: "Toml." & astToStr(fn) & ": \'" & typeName &
|
||
|
"\' not allowed at top level Toml, called from" &
|
||
|
$instantiationInfo().}
|
||
|
|
||
|
template decode*(_: type Toml,
|
||
|
input: string,
|
||
|
RecordType: type TomlNotTopLevel,
|
||
|
params: varargs[untyped]): auto =
|
||
|
# TODO, this is duplicated only due to a Nim bug:
|
||
|
# If `input` was `string|openArray[byte]`, it won't match `seq[byte]`
|
||
|
tomlFatalImpl(decode, RecordType)
|
||
|
|
||
|
template decode*(_: type Toml,
|
||
|
input: openArray[byte],
|
||
|
RecordType: type TomlNotTopLevel,
|
||
|
params: varargs[untyped]): auto =
|
||
|
# TODO, this is duplicated only due to a Nim bug:
|
||
|
# If `input` was `string|openArray[byte]`, it won't match `seq[byte]`
|
||
|
tomlFatalImpl(decode, RecordType)
|
||
|
|
||
|
template loadFile*(_: type Toml,
|
||
|
fileName: string,
|
||
|
RecordType: type TomlNotTopLevel,
|
||
|
params: varargs[untyped]): auto =
|
||
|
tomlFatalImpl(loadFile, RecordType)
|
||
|
|
||
|
template encode*(_: type Toml,
|
||
|
value: TomlNotTopLevel,
|
||
|
params: varargs[untyped]): auto =
|
||
|
type RecordType = type value
|
||
|
tomlFatalImpl(encode, RecordType)
|
||
|
|
||
|
template saveFile*(_: type Toml,
|
||
|
fileName: string,
|
||
|
value: TomlNotTopLevel,
|
||
|
params: varargs[untyped]) =
|
||
|
type RecordType = type value
|
||
|
tomlFatalImpl(saveFile, RecordType)
|
||
|
|
||
|
# override default behaviour when in keyed mode
|
||
|
import
|
||
|
stew/shims/macros
|
||
|
|
||
|
template tomlDecodeImpl*(input: untyped,
|
||
|
RecordType: distinct type,
|
||
|
key: string,
|
||
|
tomlCase: TomlCase,
|
||
|
params: varargs[untyped]): auto =
|
||
|
|
||
|
mixin init, ReaderType
|
||
|
{.noSideEffect.}:
|
||
|
# We assume that there are no side-effects here, because we are
|
||
|
# using a `memoryInput`. The computed side-effects are coming
|
||
|
# from the fact that the dynamic dispatch mechanisms used in
|
||
|
# faststreams may be reading from a file or a network device.
|
||
|
try:
|
||
|
var stream = unsafeMemoryInput(input)
|
||
|
var reader = unpackArgs(init, [TomlReader, stream, tomlCase, params])
|
||
|
when RecordType is (seq or array) and uTypeIsRecord(RecordType):
|
||
|
reader.readTableArray(RecordType, key, tomlCase)
|
||
|
else:
|
||
|
reader.moveToKey(key, tomlCase)
|
||
|
reader.readValue(RecordType)
|
||
|
except IOError:
|
||
|
raise (ref Defect)() # memory inputs cannot raise an IOError
|
||
|
|
||
|
template decode*(_: type Toml, input: string,
|
||
|
RecordType: distinct type,
|
||
|
key: string, tomlCase: TomlCase,
|
||
|
params: varargs[untyped]): auto =
|
||
|
tomlDecodeImpl(input, RecordType, key, tomlCase, params)
|
||
|
|
||
|
template decode*(_: type Toml, input: string,
|
||
|
RecordType: distinct type,
|
||
|
key: string, params: varargs[untyped]): auto =
|
||
|
tomlDecodeImpl(input, RecordType, key, TomlCaseSensitive, params)
|
||
|
|
||
|
template decode*(_: type Toml, input: openArray[byte],
|
||
|
RecordType: distinct type,
|
||
|
key: string, tomlCase: TomlCase,
|
||
|
params: varargs[untyped]): auto =
|
||
|
tomlDecodeImpl(input, RecordType, key, tomlCase, params)
|
||
|
|
||
|
template decode*(_: type Toml, input: openArray[byte],
|
||
|
RecordType: distinct type,
|
||
|
key: string, params: varargs[untyped]): auto =
|
||
|
tomlDecodeImpl(input, RecordType, key, TomlCaseSensitive, params)
|
||
|
|
||
|
|
||
|
template tomlLoadImpl*(filename: string,
|
||
|
RecordType: distinct type,
|
||
|
key: string, tomlCase: TomlCase,
|
||
|
params: varargs[untyped]): auto =
|
||
|
|
||
|
mixin init, ReaderType, readValue
|
||
|
|
||
|
var stream = memFileInput(filename)
|
||
|
try:
|
||
|
var reader = unpackArgs(init, [TomlReader, stream, params])
|
||
|
when RecordType is (seq or array) and uTypeIsRecord(RecordType):
|
||
|
reader.readTableArray(RecordType, key, tomlCase)
|
||
|
else:
|
||
|
reader.moveToKey(key, tomlCase)
|
||
|
reader.readValue(RecordType)
|
||
|
finally:
|
||
|
close stream
|
||
|
|
||
|
template loadFile*(_: type Toml, filename: string,
|
||
|
RecordType: distinct type,
|
||
|
key: string, tomlCase: TomlCase,
|
||
|
params: varargs[untyped]): auto =
|
||
|
tomlLoadImpl(filename, RecordType, key, tomlCase, params)
|
||
|
|
||
|
template loadFile*(_: type Toml, filename: string,
|
||
|
RecordType: distinct type,
|
||
|
key: string, params: varargs[untyped]): auto =
|
||
|
tomlLoadImpl(filename, RecordType, key, TomlCaseSensitive, params)
|