Fixed presenter bug

* Fixed TagIds for Nim's system types
 * Output JSON integers for Nim's integer types
 * Output JSON floats for Nim's float types
This commit is contained in:
Felix Krause 2016-03-20 19:55:23 +01:00
parent a9b565c35c
commit 57b4518564
4 changed files with 59 additions and 52 deletions

View File

@ -366,7 +366,7 @@ proc present*(s: var YamlStream, target: Stream, tagLib: TagLibrary,
if options.style == psJson:
let hint = guessType(item.scalarContent)
if item.scalarTag in [yTagQuestionMark, yTagBoolean] and
hint in [yTypeBoolTrue, yTypeBoolFalse]:
hint in {yTypeBoolTrue, yTypeBoolFalse}:
if hint == yTypeBoolTrue:
safeWrite("true")
else:
@ -374,11 +374,15 @@ proc present*(s: var YamlStream, target: Stream, tagLib: TagLibrary,
elif item.scalarTag in [yTagQuestionMark, yTagNull] and
hint == yTypeNull:
safeWrite("null")
elif item.scalarTag in [yTagQuestionMark, yTagInteger] and
elif item.scalarTag in [yTagQuestionMark, yTagInteger,
yTagNimInt8, yTagNimInt16, yTagNimInt32, yTagNimInt64,
yTagNimUInt8, yTagNimUInt16, yTagNimUInt32,
yTagNimUInt64] and
hint == yTypeInteger:
safeWrite(item.scalarContent)
elif item.scalarTag in [yTagQuestionMark, yTagFloat] and
hint in [yTypeFloatInf, yTypeFloatNaN]:
elif item.scalarTag in [yTagQuestionMark, yTagFloat,
yTagNimFloat32, yTagNimFloat64] and
hint in {yTypeFloatInf, yTypeFloatNaN}:
raise newException(YamlPresenterJsonError,
"Infinity and not-a-number values cannot be presented as JSON!")
elif item.scalarTag in [yTagQuestionMark, yTagFloat] and

View File

@ -18,59 +18,11 @@ proc newSerializationContext(s: AnchorStyle): SerializationContext =
result.refs = initTable[pointer, AnchorId]()
result.style = s
result.nextAnchorId = 0.AnchorId
proc initSerializationTagLibrary(): TagLibrary {.raises: [].} =
result = initTagLibrary()
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
var
serializationTagLibrary* = initSerializationTagLibrary() ## \
## contains all local tags that are used for type serialization. Does
## not contain any of the specific default tags for sequences or maps,
## as those are not suited for Nim's static type system.
##
## Should not be modified manually. Will be extended by
## `serializable <#serializable,stmt,stmt>`_.
template presentTag*(t: typedesc, ts: TagStyle): TagId =
## Get the TagId that represents the given type in the given style
if ts == tsNone: yTagQuestionMark else: yamlTag(t)
template setTagUriForType*(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.
let id {.gensym.} = serializationTagLibrary.registerUri(uri)
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
## you choose a symbol for the `TagId <#TagId>`_ of the uri. This is only
## necessary if you want to implement serialization / construction yourself.
let idName* = serializationTagLibrary.registerUri(uri)
proc yamlTag*(T: typedesc[t]): TagId {.inline, raises: [].} =
## autogenerated
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)
proc lazyLoadTag(uri: string): TagId {.inline, raises: [].} =
try: result = serializationTagLibrary.tags[uri]
except KeyError: result = serializationTagLibrary.registerUri(uri)

View File

@ -65,3 +65,15 @@ proc initExtendedTagLibrary(): TagLibrary =
result.tags["tag:yaml.org,2002:timestamp"] = yTagTimestamp
result.tags["tag:yaml.org,2002:value"] = yTagValue
result.tags["tag:yaml.org,2002:yaml"] = yTagYaml
proc initSerializationTagLibrary(): TagLibrary =
result = initTagLibrary()
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

View File

@ -496,6 +496,8 @@ proc initExtendedTagLibrary*(): TagLibrary {.raises: [].}
## - ``!!value``
## - ``!!yaml``
proc initSerializationTagLibrary(): TagLibrary {.raises: [].}
proc guessType*(scalar: string): TypeHint {.raises: [].}
## Parse scalar string according to the RegEx table documented at
## `TypeHint <#TypeHind>`_.
@ -605,6 +607,43 @@ proc dump*[K](value: K, target: Stream, tagStyle: TagStyle = tsRootOnly,
{.raises: [YamlPresenterJsonError, YamlPresenterOutputError].}
## Dump a Nim value as YAML character stream.
var
serializationTagLibrary* = initSerializationTagLibrary() ## \
## contains all local tags that are used for type serialization. Does
## not contain any of the specific default tags for sequences or maps,
## as those are not suited for Nim's static type system.
##
## Should not be modified manually. Will be extended by
## `serializable <#serializable,stmt,stmt>`_.
template setTagUriForType*(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.
let id {.gensym.} = serializationTagLibrary.registerUri(uri)
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
## you choose a symbol for the `TagId <#TagId>`_ of the uri. This is only
## necessary if you want to implement serialization / construction yourself.
let idName* = serializationTagLibrary.registerUri(uri)
proc yamlTag*(T: typedesc[t]): TagId {.inline, raises: [].} = idName
## autogenerated
# 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)
# implementation
include private.tagLibrary