NimYAML/yaml/taglib.nim

88 lines
3.3 KiB
Nim

# NimYAML - YAML implementation in Nim
# (c) Copyright 2015-2023 Felix Krause
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
## ==================
## Module yaml/taglib
## ==================
##
## The taglib API enables you to define custom tags for the types you are
## using with the serialization API.
import macros
import data
template n(suffix: string): Tag = Tag(nimyamlTagRepositoryPrefix & suffix)
var
registeredUris {.compileTime.} = newSeq[string]() ## \
## Since Table doesn't really work at compile time, we also store
## registered URIs here to be able to generate a static compiler error
## when the user tries to register an URI more than once.
template setTag*(t: typedesc, tag: Tag) =
## Associate the given uri with a certain type. This uri is used as YAML tag
## when loading and dumping values of this type.
when $tag in registeredUris:
{. fatal: "[NimYAML] URI \"" & uri & "\" registered twice!" .}
const tconst {.genSym.} = tag
static:
registeredUris.add($tag)
proc yamlTag*(T: typedesc[t]): Tag {.inline, raises: [].} = tconst
## autogenerated
template setTag*(t: typedesc, tag: Tag, idName: untyped) =
## Like `setTagUri <#setTagUri.t,typedesc,string>`_, but lets
## you choose a symbol for the `TagId <#TagId>`_ of the uri. This is only
## necessary if you want to implement serialization / construction yourself.
when $tag in registeredUris:
{. fatal: "[NimYAML] URI \"" & uri & "\" registered twice!" .}
const idName* = tag
static:
registeredUris.add($tag)
proc yamlTag*(T: typedesc[t]): Tag {.inline, raises: [].} = idName
## autogenerated
template setTagUri*(t: typedesc; uri: string) {.deprecated: "use setTag".} =
setTag(t, Tag(uri))
template setTagUri*(t: typedesc; uri: string; idName: untyped)
{.deprecated: "use setTag".} = setTag(t, Tag(uri), idName)
static:
# standard YAML tags used by serialization
registeredUris.add($yTagExclamationMark)
registeredUris.add($yTagQuestionMark)
registeredUris.add($yTagString)
registeredUris.add($yTagNull)
registeredUris.add($yTagBoolean)
registeredUris.add($yTagFloat)
registeredUris.add($yTagTimestamp)
registeredUris.add($yTagValue)
registeredUris.add($yTagBinary)
# special tags used by serialization
registeredUris.add($yTagNimField)
# tags for Nim's standard types
setTag(char, n"system:char", yTagNimChar)
setTag(int8, n"system:int8", yTagNimInt8)
setTag(int16, n"system:int16", yTagNimInt16)
setTag(int32, n"system:int32", yTagNimInt32)
setTag(int64, n"system:int64", yTagNimInt64)
setTag(uint8, n"system:uint8", yTagNimUInt8)
setTag(uint16, n"system:uint16", yTagNimUInt16)
setTag(uint32, n"system:uint32", yTagNimUInt32)
setTag(uint64, n"system:uint64", yTagNimUInt64)
setTag(float32, n"system:float32", yTagNimFloat32)
setTag(float64, n"system:float64", yTagNimFloat64)
proc nimTag*(suffix: string): Tag =
## prepends NimYAML's tag repository prefix to the given suffix. For example,
## ``nimTag("system:char")`` yields ``"tag:nimyaml.org,2016:system:char"``.
Tag(nimyamlTagRepositoryPrefix & suffix)
proc initNimYamlTagHandle*(): seq[tuple[handle, uriPrefix: string]] =
## returns a seq describing the tag handle ``!n!`` referencing the NimYAML
## tag namespace. Can be used with SerializationOptions.
result = @[("!n!", nimyamlTagRepositoryPrefix)]