improved setTagUri

* renamed setTagUriForType to setTagUri
 * generated TagId is now const (can be used in case etc)
 * Uses compile-time counter independent from tag library
This commit is contained in:
Felix Krause 2016-04-21 18:58:53 +02:00
parent 62fa366ac7
commit 273093e390
4 changed files with 47 additions and 42 deletions

View File

@ -238,8 +238,8 @@ Defining a custom tag uri for a type
level, experience: int32
drops: seq[string]
setTagUriForType(Mob, "!Mob")
setTagUriForType(seq[string], "!Drops")
setTagUri(Mob, "!Mob")
setTagUri(seq[string], "!Drops")
var mob = Mob(level: 42, experience: 1800, drops:
@["Sword of Mob Slaying"])
@ -352,8 +352,7 @@ Processing a Sequence of Heterogeneous Items
type Person = object
name: string
setTagUriForType(Person, "!nim:demo:Person",
yTagPerson)
setTagUri(Person, "!nim:demo:Person", yTagPerson)
var
s = newFileStream("in.yaml", fmRead)
@ -367,7 +366,7 @@ Processing a Sequence of Heterogeneous Items
while nextEvent.kind != yamlEndSeq:
var curTag = nextEvent.tag()
if curTag == yTagQuestionMark:
# we only support implicitly tagged scalar events
# we only support implicitly tagged scalars
assert nextEvent.kind == yamlScalar
case guessType(nextEvent.scalarContent)
of yTypeInteger: curTag = yTagInteger
@ -390,14 +389,11 @@ Processing a Sequence of Heterogeneous Items
var b: bool
events.constructChild(context, b)
echo "got boolean: ", b
else:
# non-standard tag ids are not available
# at compile time
if curTag == yTagPerson:
var p: Person
events.constructChild(context, p)
echo "got Person with name: ", p.name
else: assert false, "unsupported tag: " & $curTag
of yTagPerson:
var p: Person
events.constructChild(context, p)
echo "got Person with name: ", p.name
else: assert false, "unsupported tag: " & $curTag
nextEvent = events.peek()
assert events.next().kind == yamlEndSeq
assert events.next().kind == yamlEndDoc

View File

@ -142,13 +142,13 @@ These tags are generated on the fly based on the types you instantiate
``Table`` or ``seq`` with.
You may customize the tags used for your types by using the template
`setTagUriForType <yaml.html#setTagUriForType.t,typedesc,string>`_. It may not
`setTagUri <yaml.html#setTagUri.t,typedesc,string>`_. It may not
be applied to scalar and collection types implemented by NimYAML, but you can
for example use it on a certain ``seq`` type:
.. code-block:: nim
setTagUriForType(seq[string], "!nim:my:seq")
setTagUri(seq[string], "!nim:my:seq")
Customize Serialization
=======================

View File

@ -30,9 +30,9 @@ type
proc `$`(v: BetterInt): string {.borrow.}
proc `==`(l, r: BetterInt): bool {.borrow.}
setTagUriForType(TrafficLight, "!tl")
setTagUriForType(Node, "!example.net:Node")
setTagUriForType(BetterInt, "!test:BetterInt")
setTagUri(TrafficLight, "!tl")
setTagUri(Node, "!example.net:Node")
setTagUri(BetterInt, "!test:BetterInt")
proc representObject*(value: BetterInt, ts: TagStyle = tsNone,
c: SerializationContext, tag: TagId): RawYamlStream {.raises: [].} =

View File

@ -633,31 +633,40 @@ var
## Should not be modified manually. Will be extended by
## `serializable <#serializable,stmt,stmt>`_.
static:
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.
var
nextStaticTagId {.compileTime.} = 100.TagId ## \
## used for generating unique TagIds with ``setTagUri``.
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 setTagUriForType*(t: typedesc, uri: string): stmt =
template setTagUri*(t: typedesc, uri: string): stmt =
## Associate the given uri with a certain type. This uri is used as YAML tag
## when loading and dumping values of this type.
when uri in registeredUris:
{. fatal: "[NimYAML] URI \"" & uri & "\" registered twice!" .}
static: registeredUris.add(uri)
let id {.gensym.} = serializationTagLibrary.registerUri(uri)
const id {.genSym.} = nextStaticTagId
static:
registeredUris.add(uri)
nextStaticTagId = TagId(int(nextStaticTagId) + 1)
when nextStaticTagId == yFirstCustomTagId:
{.fatal: "Too many tags!".}
serializationTagLibrary.tags[uri] = id
proc yamlTag*(T: typedesc[t]): TagId {.inline, raises: [].} = id
## autogenerated
template setTagUriForType*(t: typedesc, uri: string, idName: expr): stmt =
## Like `setTagUriForType <#setTagUriForType,typedesc,string>`_, but lets
template setTagUri*(t: typedesc, uri: string, idName: expr): stmt =
## 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 uri in registeredUris:
{. fatal: "[NimYAML] URI \"" & uri & "\" registered twice!" .}
static: registeredUris.add(uri)
let idName* = serializationTagLibrary.registerUri(uri)
const idName* = nextStaticTagId
static:
registeredUris.add(uri)
nextStaticTagId = TagId(int(nextStaticTagId) + 1)
serializationTagLibrary.tags[uri] = idName
proc yamlTag*(T: typedesc[t]): TagId {.inline, raises: [].} = idName
## autogenerated
@ -678,17 +687,17 @@ static:
registeredUris.add("!nim:nil:seq")
# tags for Nim's standard types
setTagUriForType(char, "!nim:system:char", yTagNimChar)
setTagUriForType(int8, "!nim:system:int8", yTagNimInt8)
setTagUriForType(int16, "!nim:system:int16", yTagNimInt16)
setTagUriForType(int32, "!nim:system:int32", yTagNimInt32)
setTagUriForType(int64, "!nim:system:int64", yTagNimInt64)
setTagUriForType(uint8, "!nim:system:uint8", yTagNimUInt8)
setTagUriForType(uint16, "!nim:system:uint16", yTagNimUInt16)
setTagUriForType(uint32, "!nim:system:uint32", yTagNimUInt32)
setTagUriForType(uint64, "!nim:system:uint64", yTagNimUInt64)
setTagUriForType(float32, "!nim:system:float32", yTagNimFloat32)
setTagUriForType(float64, "!nim:system:float64", yTagNimFloat64)
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)
# implementation