nim-serde/serde/pragmas.nim
2024-02-07 09:40:48 +11:00

71 lines
2.6 KiB
Nim

import std/macros
import ./types
type
SerdeFieldOptions* = object
key*: string
ignore*: bool
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.} =
var result = paramValue == T.default
when T is SerdeMode:
return paramValue == SerdeMode.OptOut
return result
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":
static: echo "decided default mode for ", T, "serialize, OptIn"
SerdeMode.OptIn
elif astToStr(pragma) == "deserialize":
static: echo "decided default mode for ", T, " deserialize, OptOut"
SerdeMode.OptOut