nim-serde/serde/pragmas.nim
2024-02-07 13:41:37 +11:00

68 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