nim-serde/serde/utils/pragmas.nim

81 lines
2.5 KiB
Nim

import std/macros
import ./types
export types
{.push raises: [].}
template serialize*(key = "", ignore = false,
mode = SerdeMode.OptOut) {.pragma.}
template deserialize*(key = "", ignore = false,
mode = SerdeMode.OptOut) {.pragma.}
proc isDefault[T](paramValue: T): bool {.compileTime.} =
when T is SerdeMode:
return paramValue == SerdeMode.OptOut
else:
return paramValue == T.default
template expectMissingPragmaParam*(value, pragma, name, msg) =
static:
when value.hasCustomPragma(pragma):
const params = value.getCustomPragmaVal(pragma)
for paramName, paramValue in params.fieldPairs:
if paramName == name and not paramValue.isDefault:
raiseAssert(msg)
template getSerdeFieldOptions*(pragma, fieldName,
fieldValue): SerdeFieldOptions =
var opts = SerdeFieldOptions(key: fieldName, ignore: false)
when fieldValue.hasCustomPragma(pragma):
fieldValue.expectMissingPragmaParam(
pragma,
"mode",
"Cannot set " & astToStr(pragma) & " 'mode' on '" & fieldName &
"' field defintion.",
)
let (key, ignore, _) = fieldValue.getCustomPragmaVal(pragma)
opts.ignore = ignore
if key != "":
opts.key = key
opts
template getSerdeMode*(T, pragma): SerdeMode =
when T.hasCustomPragma(pragma):
T.expectMissingPragmaParam(
pragma,
"key",
"Cannot set " & astToStr(pragma) & " 'key' on '" & $T &
"' type definition.",
)
T.expectMissingPragmaParam(
pragma,
"ignore",
"Cannot set " & astToStr(pragma) & " 'ignore' on '" & $T &
"' type definition.",
)
let (_, _, mode) = T.getCustomPragmaVal(pragma)
mode
else:
# Default mode -- when the type is NOT annotated with a
# serialize/deserialize pragma.
#
# NOTE This may be different in the logic branch above, when the type is
# annotated with serialize/deserialize but doesn't specify a mode. The
# default in that case will fallback to the default mode specified in the
# pragma signature (currently OptOut for both serialize and deserialize)
#
# Examples:
# 1. type MyObj = object
# Type is not annotated, mode defaults to OptOut (as specified on the
# pragma signatures) for both serialization and deserializtion
#
# 2. type MyObj {.serialize, deserialize.} = object
# Type is annotated, mode defaults to OptIn for serialization and OptOut
# for deserialization
when astToStr(pragma) == "serialize":
SerdeMode.OptIn
elif astToStr(pragma) == "deserialize":
SerdeMode.OptOut