mirror of https://github.com/status-im/NimYAML.git
Use global tag handle for NimYAML
* NimYAML now uses the tag prefix tag:nimyaml.org,2016: * That tag handle is shortened to !n! when presenting * Also fixed some minor bugs dealing with tag handles
This commit is contained in:
parent
fa14a11957
commit
29352fa4fe
|
@ -1,5 +1,6 @@
|
|||
%YAML 1.2
|
||||
--- !nim:system:seq(nim:custom:Person)
|
||||
%TAG !n! tag:nimyaml.org,2016:
|
||||
--- !n!system:seq(tag:nimyaml.org;2016:custom:Person)
|
||||
-
|
||||
name: Karl Koch
|
||||
age: 23
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
%YAML 1.1
|
||||
%TAG !n! tag:nimyaml.org,2016:
|
||||
---
|
||||
!nim:system:seq(nim:custom:Person) [
|
||||
!nim:custom:Person {
|
||||
? !nim:field "name"
|
||||
!n!system:seq(tag:nimyaml.org;2016:custom:Person) [
|
||||
!n!custom:Person {
|
||||
? !n!field "name"
|
||||
: !!str "Karl Koch",
|
||||
? !nim:field "age"
|
||||
: !nim:system:int32 "23"
|
||||
? !n!field "age"
|
||||
: !n!system:int32 "23"
|
||||
},
|
||||
!nim:custom:Person {
|
||||
? !nim:field "name"
|
||||
!n!custom:Person {
|
||||
? !n!field "name"
|
||||
: !!str "Peter Pan",
|
||||
? !nim:field "age"
|
||||
: !nim:system:int32 "12"
|
||||
? !n!field "age"
|
||||
: !n!system:int32 "12"
|
||||
}
|
||||
]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
%YAML 1.2
|
||||
--- !nim:custom:NodeObj &a
|
||||
%TAG !n! tag:nimyaml.org,2016:
|
||||
--- !n!custom:NodeObj &a
|
||||
name: Node 1
|
||||
left:
|
||||
name: Node 2
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
%YAML 1.2
|
||||
--- !nim:custom:NodeObj &a
|
||||
%TAG !n! tag:nimyaml.org,2016:
|
||||
--- !n!custom:NodeObj &a
|
||||
name: Node 1
|
||||
left:
|
||||
name: Node 2
|
||||
left: ~
|
||||
right: &b
|
||||
right: &b
|
||||
name: Node 3
|
||||
left: *a
|
||||
right: ~
|
||||
right: *b
|
||||
right: *b
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
%YAML 1.2
|
||||
%TAG !n! tag:nimyaml.org,2016:
|
||||
--- !Mob
|
||||
!nim:field level: !nim:system:int32 42
|
||||
!nim:field experience: !nim:system:int32 1800
|
||||
!nim:field drops: !Drops [!!str Sword of Mob Slaying]
|
||||
!n!field level: !n!system:int32 42
|
||||
!n!field experience: !n!system:int32 1800
|
||||
!n!field drops: !Drops [!!str Sword of Mob Slaying]
|
||||
|
|
|
@ -19,7 +19,7 @@ type
|
|||
of ckNone:
|
||||
discard
|
||||
|
||||
setTagUri(Person, "!nim:demo:Person")
|
||||
setTagUri(Person, nimTag("demo:Person"))
|
||||
|
||||
# tell NimYAML to use Container as implicit type.
|
||||
# only possible with variant object types where
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
%YAML 1.2
|
||||
%TAG !n! tag:nimyaml.org,2016:
|
||||
---
|
||||
- this is a string
|
||||
- 42
|
||||
- false
|
||||
- !!str 23
|
||||
- !nim:demo:Person {name: Trillian}
|
||||
- !n!demo:Person {name: Trillian}
|
||||
- !!null
|
|
@ -2,7 +2,7 @@ import yaml, streams
|
|||
type Person = object
|
||||
name: string
|
||||
|
||||
setTagUri(Person, "!nim:demo:Person", yTagPerson)
|
||||
setTagUri(Person, nimTag("demo:Person"), yTagPerson)
|
||||
|
||||
var
|
||||
s = newFileStream("in.yaml", fmRead)
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
%YAML 1.2
|
||||
%TAG !n! tag:nimyaml.org,2016:
|
||||
--- !!seq
|
||||
- this is a string
|
||||
- 42
|
||||
- false
|
||||
- !!str 23
|
||||
- !nim:demo:Person {name: Trillian}
|
||||
- !n!demo:Person {name: Trillian}
|
|
@ -45,6 +45,8 @@ setTagUri(TrafficLight, "!tl")
|
|||
setTagUri(Node, "!example.net:Node")
|
||||
setTagUri(BetterInt, "!test:BetterInt")
|
||||
|
||||
const yamlDirs = "%YAML 1.2\n%TAG !n! tag:nimyaml.org,2016:\n--- "
|
||||
|
||||
proc representObject*(value: BetterInt, ts: TagStyle = tsNone,
|
||||
c: SerializationContext, tag: TagId) {.raises: [].} =
|
||||
var
|
||||
|
@ -104,7 +106,7 @@ suite "Serialization":
|
|||
test "Dump integer without fixed length":
|
||||
var input = -4247
|
||||
var output = dump(input, tsNone, asTidy, blockOnly)
|
||||
assertStringEqual "%YAML 1.2\n--- \n\"-4247\"", output
|
||||
assertStringEqual yamlDirs & "\n\"-4247\"", output
|
||||
|
||||
when sizeof(int) == sizeof(int64):
|
||||
input = int(int32.high) + 1
|
||||
|
@ -162,7 +164,7 @@ suite "Serialization":
|
|||
assert(result == 14)
|
||||
|
||||
test "Load nil string":
|
||||
let input = newStringStream("!nim:nil:string \"\"")
|
||||
let input = newStringStream("!<tag:nimyaml.org,2016:nil:string> \"\"")
|
||||
var result: string
|
||||
load(input, result)
|
||||
assert isNil(result)
|
||||
|
@ -170,7 +172,7 @@ suite "Serialization":
|
|||
test "Dump nil string":
|
||||
let input: string = nil
|
||||
var output = dump(input, tsNone, asTidy, blockOnly)
|
||||
assertStringEqual "%YAML 1.2\n--- \n!nim:nil:string \"\"", output
|
||||
assertStringEqual yamlDirs & "\n!n!nil:string \"\"", output
|
||||
|
||||
test "Load string sequence":
|
||||
let input = newStringStream(" - a\n - b")
|
||||
|
@ -183,10 +185,10 @@ suite "Serialization":
|
|||
test "Dump string sequence":
|
||||
var input = @["a", "b"]
|
||||
var output = dump(input, tsNone, asTidy, blockOnly)
|
||||
assertStringEqual "%YAML 1.2\n--- \n- a\n- b", output
|
||||
assertStringEqual yamlDirs & "\n- a\n- b", output
|
||||
|
||||
test "Load nil seq":
|
||||
let input = newStringStream("!nim:nil:seq \"\"")
|
||||
let input = newStringStream("!<tag:nimyaml.org,2016:nil:seq> \"\"")
|
||||
var result: seq[int]
|
||||
load(input, result)
|
||||
assert isNil(result)
|
||||
|
@ -194,7 +196,7 @@ suite "Serialization":
|
|||
test "Dump nil seq":
|
||||
let input: seq[int] = nil
|
||||
var output = dump(input, tsNone, asTidy, blockOnly)
|
||||
assertStringEqual "%YAML 1.2\n--- \n!nim:nil:seq \"\"", output
|
||||
assertStringEqual yamlDirs & "\n!n!nil:seq \"\"", output
|
||||
|
||||
test "Load char set":
|
||||
let input = newStringStream("- a\n- b")
|
||||
|
@ -207,7 +209,7 @@ suite "Serialization":
|
|||
test "Dump char set":
|
||||
var input = {'a', 'b'}
|
||||
var output = dump(input, tsNone, asTidy, blockOnly)
|
||||
assertStringEqual "%YAML 1.2\n--- \n- a\n- b", output
|
||||
assertStringEqual yamlDirs & "\n- a\n- b", output
|
||||
|
||||
test "Load array":
|
||||
let input = newStringStream("- 23\n- 42\n- 47")
|
||||
|
@ -220,7 +222,7 @@ suite "Serialization":
|
|||
test "Dump array":
|
||||
let input = [23'i32, 42'i32, 47'i32]
|
||||
var output = dump(input, tsNone, asTidy, blockOnly)
|
||||
assertStringEqual "%YAML 1.2\n--- \n- 23\n- 42\n- 47", output
|
||||
assertStringEqual yamlDirs & "\n- 23\n- 42\n- 47", output
|
||||
|
||||
test "Load Table[int, string]":
|
||||
let input = newStringStream("23: dreiundzwanzig\n42: zweiundvierzig")
|
||||
|
@ -235,7 +237,7 @@ suite "Serialization":
|
|||
input[23] = "dreiundzwanzig"
|
||||
input[42] = "zweiundvierzig"
|
||||
var output = dump(input, tsNone, asTidy, blockOnly)
|
||||
assertStringEqual("%YAML 1.2\n--- \n23: dreiundzwanzig\n42: zweiundvierzig",
|
||||
assertStringEqual(yamlDirs & "\n23: dreiundzwanzig\n42: zweiundvierzig",
|
||||
output)
|
||||
|
||||
test "Load OrderedTable[tuple[int32, int32], string]":
|
||||
|
@ -259,8 +261,8 @@ suite "Serialization":
|
|||
input.add((a: 23'i32, b: 42'i32), "dreiundzwanzigzweiundvierzig")
|
||||
input.add((a: 13'i32, b: 47'i32), "dreizehnsiebenundvierzig")
|
||||
var output = dump(input, tsRootOnly, asTidy, blockOnly)
|
||||
assertStringEqual("""%YAML 1.2
|
||||
--- !nim:tables:OrderedTable(nim:tuple(nim:system:int32,nim:system:int32),tag:yaml.org,2002:str)
|
||||
assertStringEqual(yamlDirs &
|
||||
"""!n!tables:OrderedTable(tag:nimyaml.org;2016:tuple(tag:nimyaml.org;2016:system:int32;tag:nimyaml.org;2016:system:int32);tag:yaml.org;2002:str)
|
||||
-
|
||||
?
|
||||
a: 23
|
||||
|
@ -284,11 +286,11 @@ suite "Serialization":
|
|||
test "Dump Sequences in Sequence":
|
||||
let input = @[@[1.int32, 2.int32, 3.int32], @[4.int32, 5.int32], @[6.int32]]
|
||||
var output = dump(input, tsNone)
|
||||
assertStringEqual "%YAML 1.2\n--- \n- [1, 2, 3]\n- [4, 5]\n- [6]", output
|
||||
assertStringEqual yamlDirs & "\n- [1, 2, 3]\n- [4, 5]\n- [6]", output
|
||||
|
||||
test "Load Enum":
|
||||
let input =
|
||||
newStringStream("!nim:system:seq(tl)\n- !tl tlRed\n- tlGreen\n- tlYellow")
|
||||
newStringStream("!<tag:nimyaml.org,2016:system:seq(tl)>\n- !tl tlRed\n- tlGreen\n- tlYellow")
|
||||
var result: seq[TrafficLight]
|
||||
load(input, result)
|
||||
assert result.len == 3
|
||||
|
@ -299,7 +301,7 @@ suite "Serialization":
|
|||
test "Dump Enum":
|
||||
let input = @[tlRed, tlGreen, tlYellow]
|
||||
var output = dump(input, tsNone, asTidy, blockOnly)
|
||||
assertStringEqual "%YAML 1.2\n--- \n- tlRed\n- tlGreen\n- tlYellow", output
|
||||
assertStringEqual yamlDirs & "\n- tlRed\n- tlGreen\n- tlYellow", output
|
||||
|
||||
test "Load Tuple":
|
||||
let input = newStringStream("str: value\ni: 42\nb: true")
|
||||
|
@ -312,7 +314,7 @@ suite "Serialization":
|
|||
test "Dump Tuple":
|
||||
let input = (str: "value", i: 42.int32, b: true)
|
||||
var output = dump(input, tsNone)
|
||||
assertStringEqual "%YAML 1.2\n--- \nstr: value\ni: 42\nb: y", output
|
||||
assertStringEqual yamlDirs & "\nstr: value\ni: 42\nb: y", output
|
||||
|
||||
test "Load Tuple - unknown field":
|
||||
let input = "str: value\nfoo: bar\ni: 42\nb: true"
|
||||
|
@ -358,8 +360,8 @@ suite "Serialization":
|
|||
test "Dump custom object":
|
||||
let input = Person(firstnamechar: 'P', surname: "Pan", age: 12)
|
||||
var output = dump(input, tsNone, asTidy, blockOnly)
|
||||
assertStringEqual(
|
||||
"%YAML 1.2\n--- \nfirstnamechar: P\nsurname: Pan\nage: 12", output)
|
||||
assertStringEqual(yamlDirs &
|
||||
"\nfirstnamechar: P\nsurname: Pan\nage: 12", output)
|
||||
|
||||
test "Load custom object - unknown field":
|
||||
let input = " firstnamechar: P\n surname: Pan\n age: 12\n occupation: free"
|
||||
|
@ -380,8 +382,8 @@ suite "Serialization":
|
|||
load(input, result)
|
||||
|
||||
test "Load sequence with explicit tags":
|
||||
let input = newStringStream("--- !nim:system:seq(" &
|
||||
"tag:yaml.org,2002:str)\n- !!str one\n- !!str two")
|
||||
let input = newStringStream(yamlDirs & "!n!system:seq(" &
|
||||
"tag:yaml.org;2002:str)\n- !!str one\n- !!str two")
|
||||
var result: seq[string]
|
||||
load(input, result)
|
||||
assert result[0] == "one"
|
||||
|
@ -390,12 +392,12 @@ suite "Serialization":
|
|||
test "Dump sequence with explicit tags":
|
||||
let input = @["one", "two"]
|
||||
var output = dump(input, tsAll, asTidy, blockOnly)
|
||||
assertStringEqual("%YAML 1.2\n--- !nim:system:seq(" &
|
||||
"tag:yaml.org,2002:str) \n- !!str one\n- !!str two", output)
|
||||
assertStringEqual(yamlDirs & "!n!system:seq(" &
|
||||
"tag:yaml.org;2002:str) \n- !!str one\n- !!str two", output)
|
||||
|
||||
test "Load custom object with explicit root tag":
|
||||
let input = newStringStream(
|
||||
"--- !nim:custom:Person\nfirstnamechar: P\nsurname: Pan\nage: 12")
|
||||
"--- !<tag:nimyaml.org,2016:custom:Person>\nfirstnamechar: P\nsurname: Pan\nage: 12")
|
||||
var result: Person
|
||||
load(input, result)
|
||||
assert result.firstnamechar == 'P'
|
||||
|
@ -405,9 +407,8 @@ suite "Serialization":
|
|||
test "Dump custom object with explicit root tag":
|
||||
let input = Person(firstnamechar: 'P', surname: "Pan", age: 12)
|
||||
var output = dump(input, tsRootOnly, asTidy, blockOnly)
|
||||
assertStringEqual("%YAML 1.2\n" &
|
||||
"--- !nim:custom:Person \nfirstnamechar: P\nsurname: Pan\nage: 12",
|
||||
output)
|
||||
assertStringEqual(yamlDirs &
|
||||
"!n!custom:Person \nfirstnamechar: P\nsurname: Pan\nage: 12", output)
|
||||
|
||||
test "Load custom variant object":
|
||||
let input = newStringStream(
|
||||
|
@ -427,8 +428,8 @@ suite "Serialization":
|
|||
let input = @[Animal(name: "Bastet", kind: akCat, purringIntensity: 7),
|
||||
Animal(name: "Anubis", kind: akDog, barkometer: 13)]
|
||||
var output = dump(input, tsNone, asTidy, blockOnly)
|
||||
assertStringEqual """%YAML 1.2
|
||||
---
|
||||
assertStringEqual yamlDirs & """
|
||||
|
||||
-
|
||||
-
|
||||
name: Bastet
|
||||
|
@ -459,8 +460,7 @@ suite "Serialization":
|
|||
b.next = c
|
||||
c.next = a
|
||||
var output = dump(a, tsRootOnly, asTidy, blockOnly)
|
||||
assertStringEqual """%YAML 1.2
|
||||
--- !example.net:Node &a
|
||||
assertStringEqual yamlDirs & """!example.net:Node &a
|
||||
value: a
|
||||
next:
|
||||
value: b
|
||||
|
@ -469,13 +469,12 @@ next:
|
|||
next: *a""", output
|
||||
|
||||
test "Load cyclic data structure":
|
||||
let input = newStringStream("""%YAML 1.2
|
||||
--- !nim:system:seq(example.net:Node)
|
||||
- &a
|
||||
let input = newStringStream(yamlDirs & """!n!system:seq(example.net:Node)
|
||||
- &a
|
||||
value: a
|
||||
next: &b
|
||||
next: &b
|
||||
value: b
|
||||
next: &c
|
||||
next: &c
|
||||
value: c
|
||||
next: *a
|
||||
- *b
|
||||
|
@ -517,8 +516,8 @@ next:
|
|||
input.add(new string)
|
||||
input[1][] = "~"
|
||||
var output = dump(input, tsRootOnly, asTidy, blockOnly)
|
||||
assertStringEqual(
|
||||
"%YAML 1.2\n--- !nim:system:seq(tag:yaml.org,2002:str) \n- !!null ~\n- !!str ~",
|
||||
assertStringEqual(yamlDirs &
|
||||
"!n!system:seq(tag:yaml.org;2002:str) \n- !!null ~\n- !!str ~",
|
||||
output)
|
||||
|
||||
test "Custom constructObject":
|
||||
|
@ -532,8 +531,7 @@ next:
|
|||
test "Custom representObject":
|
||||
let input = @[1.BetterInt, 9998887.BetterInt, 98312.BetterInt]
|
||||
var output = dump(input, tsAll, asTidy, blockOnly)
|
||||
assertStringEqual """%YAML 1.2
|
||||
--- !nim:system:seq(test:BetterInt)
|
||||
assertStringEqual yamlDirs & """!n!system:seq(test:BetterInt)
|
||||
- !test:BetterInt 1
|
||||
- !test:BetterInt 9_998_887
|
||||
- !test:BetterInt 98_312""", output
|
||||
|
|
|
@ -413,12 +413,10 @@ proc writeTagAndAnchor(target: PresenterTarget, tag: TagId,
|
|||
try:
|
||||
if tag notin [yTagQuestionMark, yTagExclamationMark]:
|
||||
let tagUri = tagLib.uri(tag)
|
||||
if tagUri.startsWith(tagLib.secondaryPrefix):
|
||||
target.append("!!")
|
||||
target.append(tagUri[18..tagUri.high])
|
||||
target.append(' ')
|
||||
elif tagUri.startsWith("!"):
|
||||
target.append(tagUri)
|
||||
let (handle, length) = tagLib.searchHandle(tagUri)
|
||||
if length > 0:
|
||||
target.append(handle)
|
||||
target.append(tagUri[length..tagUri.high])
|
||||
target.append(' ')
|
||||
else:
|
||||
target.append("!<")
|
||||
|
@ -461,8 +459,15 @@ proc doPresent(s: var YamlStream, target: PresenterTarget,
|
|||
of ov1_2: target.append("%YAML 1.2" & newline)
|
||||
of ov1_1: target.append("%YAML 1.1" & newLine)
|
||||
of ovNone: discard
|
||||
if tagLib.secondaryPrefix != yamlTagRepositoryPrefix:
|
||||
target.append("%TAG !! " & tagLib.secondaryPrefix & newline)
|
||||
for prefix, handle in tagLib.handles():
|
||||
if handle == "!":
|
||||
if prefix != "!":
|
||||
target.append("%TAG ! " & prefix & newline)
|
||||
elif handle == "!!":
|
||||
if prefix != yamlTagRepositoryPrefix:
|
||||
target.append("%TAG !! " & prefix & newline)
|
||||
else:
|
||||
target.append("%TAG " & handle & ' ' & prefix & newline)
|
||||
target.append("--- ")
|
||||
except:
|
||||
var e = newException(YamlPresenterOutputError, "")
|
||||
|
|
|
@ -104,9 +104,17 @@ proc lazyLoadTag(uri: string): TagId {.inline, raises: [].} =
|
|||
|
||||
proc safeTagUri(id: TagId): string {.raises: [].} =
|
||||
try:
|
||||
let uri = serializationTagLibrary.uri(id)
|
||||
if uri.len > 0 and uri[0] == '!': return uri[1..uri.len - 1]
|
||||
else: return uri
|
||||
var
|
||||
uri = serializationTagLibrary.uri(id)
|
||||
i = 0
|
||||
# '!' is not allowed inside a tag handle
|
||||
if uri.len > 0 and uri[0] == '!': uri = uri[1..^1]
|
||||
# ',' is not allowed after a tag handle in the suffix because it's a flow
|
||||
# indicator
|
||||
for c in uri.mitems():
|
||||
if c == ',': c = ';'
|
||||
inc(i)
|
||||
return uri
|
||||
except KeyError: internalError("Unexpected KeyError for TagId " & $id)
|
||||
|
||||
proc constructionError(s: YamlStream, msg: string): ref YamlConstructionError =
|
||||
|
@ -314,11 +322,11 @@ proc representObject*(value: char, ts: TagStyle, c: SerializationContext,
|
|||
c.put(scalarEvent("" & value, tag, yAnchorNone))
|
||||
|
||||
proc yamlTag*[I](T: typedesc[seq[I]]): TagId {.inline, raises: [].} =
|
||||
let uri = "!nim:system:seq(" & safeTagUri(yamlTag(I)) & ')'
|
||||
let uri = nimTag("system:seq(" & safeTagUri(yamlTag(I)) & ')')
|
||||
result = lazyLoadTag(uri)
|
||||
|
||||
proc yamlTag*[I](T: typedesc[set[I]]): TagId {.inline, raises: [].} =
|
||||
let uri = "!nim:system:set(" & safeTagUri(yamlTag(I)) & ')'
|
||||
let uri = nimTag("system:set(" & safeTagUri(yamlTag(I)) & ')')
|
||||
result = lazyLoadTag(uri)
|
||||
|
||||
proc constructObject*[T](s: var YamlStream, c: ConstructionContext,
|
||||
|
@ -360,8 +368,8 @@ proc representObject*[T](value: seq[T]|set[T], ts: TagStyle,
|
|||
|
||||
proc yamlTag*[I, V](T: typedesc[array[I, V]]): TagId {.inline, raises: [].} =
|
||||
const rangeName = name(I)
|
||||
let uri = "!nim:system:array(" & rangeName[6..rangeName.high()] & "," &
|
||||
safeTagUri(yamlTag(V)) & ')'
|
||||
let uri = nimTag("system:array(" & rangeName[6..rangeName.high()] & ';' &
|
||||
safeTagUri(yamlTag(V)) & ')')
|
||||
result = lazyLoadTag(uri)
|
||||
|
||||
proc constructObject*[I, T](s: var YamlStream, c: ConstructionContext,
|
||||
|
@ -391,8 +399,8 @@ proc representObject*[I, T](value: array[I, T], ts: TagStyle,
|
|||
|
||||
proc yamlTag*[K, V](T: typedesc[Table[K, V]]): TagId {.inline, raises: [].} =
|
||||
try:
|
||||
let uri = "!nim:tables:Table(" & safeTagUri(yamlTag(K)) & "," &
|
||||
safeTagUri(yamlTag(V)) & ")"
|
||||
let uri = nimTag("tables:Table(" & safeTagUri(yamlTag(K)) & ';' &
|
||||
safeTagUri(yamlTag(V)) & ")")
|
||||
result = lazyLoadTag(uri)
|
||||
except KeyError:
|
||||
# cannot happen (theoretically, you know)
|
||||
|
@ -430,8 +438,8 @@ proc representObject*[K, V](value: Table[K, V], ts: TagStyle,
|
|||
proc yamlTag*[K, V](T: typedesc[OrderedTable[K, V]]): TagId
|
||||
{.inline, raises: [].} =
|
||||
try:
|
||||
let uri = "!nim:tables:OrderedTable(" & safeTagUri(yamlTag(K)) & "," &
|
||||
safeTagUri(yamlTag(V)) & ")"
|
||||
let uri = nimTag("tables:OrderedTable(" & safeTagUri(yamlTag(K)) & ';' &
|
||||
safeTagUri(yamlTag(V)) & ")")
|
||||
result = lazyLoadTag(uri)
|
||||
except KeyError:
|
||||
# cannot happen (theoretically, you know)
|
||||
|
@ -475,7 +483,7 @@ proc representObject*[K, V](value: OrderedTable[K, V], ts: TagStyle,
|
|||
|
||||
proc yamlTag*(T: typedesc[object|enum]):
|
||||
TagId {.inline, raises: [].} =
|
||||
var uri = "!nim:custom:" & (typetraits.name(type(T)))
|
||||
var uri = nimTag("custom:" & (typetraits.name(type(T))))
|
||||
try: serializationTagLibrary.tags[uri]
|
||||
except KeyError: serializationTagLibrary.registerUri(uri)
|
||||
|
||||
|
@ -483,7 +491,7 @@ proc yamlTag*(T: typedesc[tuple]):
|
|||
TagId {.inline, raises: [].} =
|
||||
var
|
||||
i: T
|
||||
uri = "!nim:tuple("
|
||||
uri = nimTag("tuple(")
|
||||
first = true
|
||||
for name, value in fieldPairs(i):
|
||||
if first: first = false
|
||||
|
@ -741,6 +749,7 @@ macro constructImplicitVariantObject(s, c, r, possibleTagIds: untyped,
|
|||
))
|
||||
ifStmt.add(newNimNode(nnkElse).add(newNimNode(nnkTryStmt).add(
|
||||
newStmtList(raiseStmt), newNimNode(nnkExceptBranch).add(
|
||||
newIdentNode("KeyError"),
|
||||
newNimNode(nnkDiscardStmt).add(newEmptyNode())
|
||||
))))
|
||||
result = newStmtList(newCall("reset", r), ifStmt)
|
||||
|
|
131
yaml/taglib.nim
131
yaml/taglib.nim
|
@ -12,7 +12,7 @@
|
|||
## and create own tags. It also enables you to define tags for types used with
|
||||
## the serialization API.
|
||||
|
||||
import tables, macros, hashes
|
||||
import tables, macros, hashes, strutils
|
||||
|
||||
type
|
||||
TagId* = distinct int ## \
|
||||
|
@ -41,7 +41,7 @@ type
|
|||
## `initExtendedTagLibrary <#initExtendedTagLibrary>`_.
|
||||
tags*: Table[string, TagId]
|
||||
nextCustomTagId*: TagId
|
||||
secondaryPrefix*: string
|
||||
tagHandles: Table[string, string]
|
||||
|
||||
const
|
||||
# failsafe schema
|
||||
|
@ -102,6 +102,7 @@ const
|
|||
## exist in the ``YamlTagLibrary`` which is used for parsing.
|
||||
|
||||
yamlTagRepositoryPrefix* = "tag:yaml.org,2002:"
|
||||
nimyamlTagRepositoryPrefix* = "tag:nimyaml.org,2016:"
|
||||
|
||||
proc `==`*(left, right: TagId): bool {.borrow.}
|
||||
proc hash*(id: TagId): Hash {.borrow.}
|
||||
|
@ -133,7 +134,7 @@ proc initTagLibrary*(): TagLibrary {.raises: [].} =
|
|||
## ``yFirstCustomTagId``.
|
||||
new(result)
|
||||
result.tags = initTable[string, TagId]()
|
||||
result.secondaryPrefix = yamlTagRepositoryPrefix
|
||||
result.tagHandles = {"!": "!", yamlTagRepositoryPrefix : "!!"}.toTable()
|
||||
result.nextCustomTagId = yFirstCustomTagId
|
||||
|
||||
proc registerUri*(tagLib: TagLibrary, uri: string): TagId {.raises: [].} =
|
||||
|
@ -149,6 +150,9 @@ proc uri*(tagLib: TagLibrary, id: TagId): string {.raises: [KeyError].} =
|
|||
if iId == id: return iUri
|
||||
raise newException(KeyError, "Unknown tag id: " & $id)
|
||||
|
||||
template y(suffix: string): string = yamlTagRepositoryPrefix & suffix
|
||||
template n(suffix: string): string = nimyamlTagRepositoryPrefix & suffix
|
||||
|
||||
proc initFailsafeTagLibrary*(): TagLibrary {.raises: [].} =
|
||||
## Contains only:
|
||||
## - ``!``
|
||||
|
@ -159,9 +163,9 @@ proc initFailsafeTagLibrary*(): TagLibrary {.raises: [].} =
|
|||
result = initTagLibrary()
|
||||
result.tags["!"] = yTagExclamationMark
|
||||
result.tags["?"] = yTagQuestionMark
|
||||
result.tags["tag:yaml.org,2002:str"] = yTagString
|
||||
result.tags["tag:yaml.org,2002:seq"] = yTagSequence
|
||||
result.tags["tag:yaml.org,2002:map"] = yTagMapping
|
||||
result.tags[y"str"] = yTagString
|
||||
result.tags[y"seq"] = yTagSequence
|
||||
result.tags[y"map"] = yTagMapping
|
||||
|
||||
proc initCoreTagLibrary*(): TagLibrary {.raises: [].} =
|
||||
## Contains everything in ``initFailsafeTagLibrary`` plus:
|
||||
|
@ -170,10 +174,10 @@ proc initCoreTagLibrary*(): TagLibrary {.raises: [].} =
|
|||
## - ``!!int``
|
||||
## - ``!!float``
|
||||
result = initFailsafeTagLibrary()
|
||||
result.tags["tag:yaml.org,2002:null"] = yTagNull
|
||||
result.tags["tag:yaml.org,2002:bool"] = yTagBoolean
|
||||
result.tags["tag:yaml.org,2002:int"] = yTagInteger
|
||||
result.tags["tag:yaml.org,2002:float"] = yTagFloat
|
||||
result.tags[y"null"] = yTagNull
|
||||
result.tags[y"bool"] = yTagBoolean
|
||||
result.tags[y"int"] = yTagInteger
|
||||
result.tags[y"float"] = yTagFloat
|
||||
|
||||
proc initExtendedTagLibrary*(): TagLibrary {.raises: [].} =
|
||||
## Contains everything from ``initCoreTagLibrary`` plus:
|
||||
|
@ -186,29 +190,29 @@ proc initExtendedTagLibrary*(): TagLibrary {.raises: [].} =
|
|||
## - ``!!value``
|
||||
## - ``!!yaml``
|
||||
result = initCoreTagLibrary()
|
||||
result.tags["tag:yaml.org,2002:omap"] = yTagOrderedMap
|
||||
result.tags["tag:yaml.org,2002:pairs"] = yTagPairs
|
||||
result.tags["tag:yaml.org,2002:binary"] = yTagBinary
|
||||
result.tags["tag:yaml.org,2002:merge"] = yTagMerge
|
||||
result.tags["tag:yaml.org,2002:timestamp"] = yTagTimestamp
|
||||
result.tags["tag:yaml.org,2002:value"] = yTagValue
|
||||
result.tags["tag:yaml.org,2002:yaml"] = yTagYaml
|
||||
|
||||
result.tags[y"omap"] = yTagOrderedMap
|
||||
result.tags[y"pairs"] = yTagPairs
|
||||
result.tags[y"binary"] = yTagBinary
|
||||
result.tags[y"merge"] = yTagMerge
|
||||
result.tags[y"timestamp"] = yTagTimestamp
|
||||
result.tags[y"value"] = yTagValue
|
||||
result.tags[y"yaml"] = yTagYaml
|
||||
|
||||
proc initSerializationTagLibrary*(): TagLibrary =
|
||||
result = initTagLibrary()
|
||||
result.tagHandles[nimyamlTagRepositoryPrefix] = "!n!"
|
||||
result.tags["!"] = yTagExclamationMark
|
||||
result.tags["?"] = yTagQuestionMark
|
||||
result.tags["tag:yaml.org,2002:str"] = yTagString
|
||||
result.tags["tag:yaml.org,2002:null"] = yTagNull
|
||||
result.tags["tag:yaml.org,2002:bool"] = yTagBoolean
|
||||
result.tags["tag:yaml.org,2002:float"] = yTagFloat
|
||||
result.tags["tag:yaml.org,2002:timestamp"] = yTagTimestamp
|
||||
result.tags["tag:yaml.org,2002:value"] = yTagValue
|
||||
result.tags["tag:yaml.org,2002:binary"] = yTagBinary
|
||||
result.tags["!nim:field"] = yTagNimField
|
||||
result.tags["!nim:nil:string"] = yTagNimNilString
|
||||
result.tags["!nim:nil:seq"] = yTagNimNilSeq
|
||||
result.tags[y"str"] = yTagString
|
||||
result.tags[y"null"] = yTagNull
|
||||
result.tags[y"bool"] = yTagBoolean
|
||||
result.tags[y"float"] = yTagFloat
|
||||
result.tags[y"timestamp"] = yTagTimestamp
|
||||
result.tags[y"value"] = yTagValue
|
||||
result.tags[y"binary"] = yTagBinary
|
||||
result.tags[n"field"] = yTagNimField
|
||||
result.tags[n"nil:string"] = yTagNimNilString
|
||||
result.tags[n"nil:seq"] = yTagNimNilSeq
|
||||
|
||||
var
|
||||
serializationTagLibrary* = initSerializationTagLibrary() ## \
|
||||
|
@ -262,27 +266,56 @@ static:
|
|||
# standard YAML tags used by serialization
|
||||
registeredUris.add("!")
|
||||
registeredUris.add("?")
|
||||
registeredUris.add("tag:yaml.org,2002:str")
|
||||
registeredUris.add("tag:yaml.org,2002:null")
|
||||
registeredUris.add("tag:yaml.org,2002:bool")
|
||||
registeredUris.add("tag:yaml.org,2002:float")
|
||||
registeredUris.add("tag:yaml.org,2002:timestamp")
|
||||
registeredUris.add("tag:yaml.org,2002:value")
|
||||
registeredUris.add("tag:yaml.org,2002:binary")
|
||||
registeredUris.add(y"str")
|
||||
registeredUris.add(y"null")
|
||||
registeredUris.add(y"bool")
|
||||
registeredUris.add(y"float")
|
||||
registeredUris.add(y"timestamp")
|
||||
registeredUris.add(y"value")
|
||||
registeredUris.add(y"binary")
|
||||
# special tags used by serialization
|
||||
registeredUris.add("!nim:field")
|
||||
registeredUris.add("!nim:nil:string")
|
||||
registeredUris.add("!nim:nil:seq")
|
||||
registeredUris.add(n"field")
|
||||
registeredUris.add(n"nil:string")
|
||||
registeredUris.add(n"nil:seq")
|
||||
|
||||
# tags for Nim's standard types
|
||||
setTagUri(char, "!nim:system:char", yTagNimChar)
|
||||
setTagUri(int8, "!nim:system:int8", yTagNimInt8)
|
||||
setTagUri(int16, "!nim:system:int16", yTagNimInt16)
|
||||
setTagUri(int32, "!nim:system:int32", yTagNimInt32)
|
||||
setTagUri(int64, "!nim:system:int64", yTagNimInt64)
|
||||
setTagUri(uint8, "!nim:system:uint8", yTagNimUInt8)
|
||||
setTagUri(uint16, "!nim:system:uint16", yTagNimUInt16)
|
||||
setTagUri(uint32, "!nim:system:uint32", yTagNimUInt32)
|
||||
setTagUri(uint64, "!nim:system:uint64", yTagNimUInt64)
|
||||
setTagUri(float32, "!nim:system:float32", yTagNimFloat32)
|
||||
setTagUri(float64, "!nim:system:float64", yTagNimFloat64)
|
||||
setTagUri(char, n"system:char", yTagNimChar)
|
||||
setTagUri(int8, n"system:int8", yTagNimInt8)
|
||||
setTagUri(int16, n"system:int16", yTagNimInt16)
|
||||
setTagUri(int32, n"system:int32", yTagNimInt32)
|
||||
setTagUri(int64, n"system:int64", yTagNimInt64)
|
||||
setTagUri(uint8, n"system:uint8", yTagNimUInt8)
|
||||
setTagUri(uint16, n"system:uint16", yTagNimUInt16)
|
||||
setTagUri(uint32, n"system:uint32", yTagNimUInt32)
|
||||
setTagUri(uint64, n"system:uint64", yTagNimUInt64)
|
||||
setTagUri(float32, n"system:float32", yTagNimFloat32)
|
||||
setTagUri(float64, n"system:float64", yTagNimFloat64)
|
||||
|
||||
proc registerHandle*(tagLib: TagLibrary, handle, prefix: string) =
|
||||
## Registers a handle for a prefix. When presenting any tag that starts with
|
||||
## this prefix, the handle is used instead. Also causes the presenter to
|
||||
## output a TAG directive for the handle.
|
||||
taglib.tagHandles[prefix] = handle
|
||||
|
||||
proc searchHandle*(tagLib: TagLibrary, tag: string):
|
||||
tuple[handle: string, len: int] {.raises: [].} =
|
||||
## search in the registered tag handles for one whose prefix matches the start
|
||||
## of the given tag. If multiple registered handles match, the one with the
|
||||
## longest prefix is returned. If no registered handle matches, (nil, 0) is
|
||||
## returned.
|
||||
result.len = 0
|
||||
for key, value in tagLib.tagHandles:
|
||||
if key.len > result.len:
|
||||
if tag.startsWith(key):
|
||||
result.len = key.len
|
||||
result.handle = value
|
||||
|
||||
iterator handles*(tagLib: TagLibrary): tuple[prefix, handle: string] =
|
||||
## iterate over registered tag handles that may be used as shortcuts
|
||||
## (e.g. ``!n!`` for ``tag:nimyaml.org,2016:``)
|
||||
for key, value in tagLib.tagHandles: yield (key, value)
|
||||
|
||||
proc nimTag*(suffix: string): string =
|
||||
## prepends NimYAML's tag repository prefix to the given suffix. For example,
|
||||
## ``nimTag("system:char")`` yields ``"tag:nimyaml.org,2016:system:char"``.
|
||||
nimyamlTagRepositoryPrefix & suffix
|
Loading…
Reference in New Issue