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)]