/ yaml / taglib.nim
taglib.nim
 1  #            NimYAML - YAML implementation in Nim
 2  #        (c) Copyright 2015-2023 Felix Krause
 3  #
 4  #    See the file "copying.txt", included in this
 5  #    distribution, for details about the copyright.
 6  
 7  ## ==================
 8  ## Module yaml/taglib
 9  ## ==================
10  ##
11  ## The taglib API enables you to define custom tags for the types you are
12  ## using with the serialization API.
13  
14  import macros
15  import data
16  
17  template n(suffix: string): Tag = Tag(nimyamlTagRepositoryPrefix & suffix)
18  
19  var
20    registeredUris {.compileTime.} = newSeq[string]() ## \
21      ## Since Table doesn't really work at compile time, we also store
22      ## registered URIs here to be able to generate a static compiler error
23      ## when the user tries to register an URI more than once.
24  
25  template setTag*(t: typedesc, tag: Tag) =
26    ## Associate the given uri with a certain type. This uri is used as YAML tag
27    ## when loading and dumping values of this type.
28    when $tag in registeredUris:
29      {. fatal: "[NimYAML] URI \"" & uri & "\" registered twice!" .}
30    const tconst {.genSym.} = tag
31    static:
32      registeredUris.add($tag)
33    proc yamlTag*(T: typedesc[t]): Tag {.inline, raises: [].} = tconst
34      ## autogenerated
35  
36  template setTag*(t: typedesc, tag: Tag, idName: untyped) =
37    ## Like `setTagUri <#setTagUri.t,typedesc,string>`_, but lets
38    ## you choose a symbol for the `TagId <#TagId>`_ of the uri. This is only
39    ## necessary if you want to implement serialization / construction yourself.
40    when $tag in registeredUris:
41      {. fatal: "[NimYAML] URI \"" & uri & "\" registered twice!" .}
42    const idName* = tag
43    static:
44      registeredUris.add($tag)
45    proc yamlTag*(T: typedesc[t]): Tag {.inline, raises: [].} = idName
46      ## autogenerated
47  
48  template setTagUri*(t: typedesc; uri: string) {.deprecated: "use setTag".} =
49    setTag(t, Tag(uri))
50  template setTagUri*(t: typedesc; uri: string; idName: untyped)
51      {.deprecated: "use setTag".} = setTag(t, Tag(uri), idName)
52  
53  static:
54    # standard YAML tags used by serialization
55    registeredUris.add($yTagExclamationMark)
56    registeredUris.add($yTagQuestionMark)
57    registeredUris.add($yTagString)
58    registeredUris.add($yTagNull)
59    registeredUris.add($yTagBoolean)
60    registeredUris.add($yTagFloat)
61    registeredUris.add($yTagTimestamp)
62    registeredUris.add($yTagValue)
63    registeredUris.add($yTagBinary)
64    # special tags used by serialization
65    registeredUris.add($yTagNimField)
66  
67  # tags for Nim's standard types
68  setTag(char, n"system:char", yTagNimChar)
69  setTag(int8, n"system:int8", yTagNimInt8)
70  setTag(int16, n"system:int16", yTagNimInt16)
71  setTag(int32, n"system:int32", yTagNimInt32)
72  setTag(int64, n"system:int64", yTagNimInt64)
73  setTag(uint8, n"system:uint8", yTagNimUInt8)
74  setTag(uint16, n"system:uint16", yTagNimUInt16)
75  setTag(uint32, n"system:uint32", yTagNimUInt32)
76  setTag(uint64, n"system:uint64", yTagNimUInt64)
77  setTag(float32, n"system:float32", yTagNimFloat32)
78  setTag(float64, n"system:float64", yTagNimFloat64)
79  
80  proc nimTag*(suffix: string): Tag =
81    ## prepends NimYAML's tag repository prefix to the given suffix. For example,
82    ## ``nimTag("system:char")`` yields ``"tag:nimyaml.org,2016:system:char"``.
83    Tag(nimyamlTagRepositoryPrefix & suffix)
84  
85  proc initNimYamlTagHandle*(): seq[tuple[handle, uriPrefix: string]] =
86    ## returns a seq describing the tag handle ``!n!`` referencing the NimYAML
87    ## tag namespace. Can be used with SerializationOptions.
88    result = @[("!n!", nimyamlTagRepositoryPrefix)]