mirror of https://github.com/status-im/NimYAML.git
Support int, uint and float types.
This commit is contained in:
parent
6ad7e33bb5
commit
58b9b92895
|
@ -47,15 +47,19 @@ further configuration.
|
|||
Scalar Types
|
||||
------------
|
||||
|
||||
The following integer types are supported by NimYAML: ``int8``, ``int16``,
|
||||
``int32``, ``int64``, ``uint8``, ``uint16``, ``uint32``, ``uint64``. Note that
|
||||
the ``int`` type is *not* supported, since its sice varies based on the target
|
||||
operation system. This makes it unfit for usage within NimYAML, because a value
|
||||
might not round-trip between a binary for a 32-bit OS and another binary for a
|
||||
64-bit OS. The same goes for ``uint``.
|
||||
The following integer types are supported by NimYAML: ``int``, ``int8``,
|
||||
``int16``, ``int32``, ``int64``, ``uint8``, ``uint16``, ``uint32``, ``uint64``.
|
||||
Note that the ``int`` type has a variable size dependent on the target
|
||||
operation system. To make sure that it round-trips properly between 32-bit and
|
||||
64-bit operating systems, it will be converted to an ``int32`` during loading
|
||||
and dumping. This will raise an exception for values outside of the range
|
||||
``int32.low .. int32.high``! If you define the types you serialize yourself,
|
||||
always consider using an integer type with explicit length. The same goes for
|
||||
``uint``.
|
||||
|
||||
The floating point types ``float32`` and ``float64`` are also supported, but
|
||||
``float`` is not, for the same reason.
|
||||
The floating point types ``float``, ``float32`` and ``float64`` are also
|
||||
supported. There is currently no problem with ``float``, because it is always a
|
||||
``float64``.
|
||||
|
||||
``string`` is supported and one of the few Nim types which directly map to a
|
||||
standard YAML type. ``char`` is also supported.
|
||||
|
|
|
@ -28,7 +28,7 @@ proc safeTagUri(id: TagId): string {.raises: [].} =
|
|||
if uri.len > 0 and uri[0] == '!': return uri[1..uri.len - 1]
|
||||
else: return uri
|
||||
except KeyError:
|
||||
# cannot happen (theoretically, you known)
|
||||
# cannot happen (theoretically, you know)
|
||||
assert(false)
|
||||
|
||||
template constructScalarItem*(s: var YamlStream, i: expr,
|
||||
|
@ -74,9 +74,11 @@ proc constructObject*[T: int8|int16|int32|int64](
|
|||
|
||||
template constructObject*(s: var YamlStream, c: ConstructionContext,
|
||||
result: var int) =
|
||||
## calling this will raise a compiler error because ``int`` is not supported
|
||||
{.fatal: "The length of `int` is platform dependent. Use int[8|16|32|64].".}
|
||||
discard
|
||||
## constructs an integer of architecture-defined length by loading it into
|
||||
## int32 and then converting it.
|
||||
var i32Result: int32
|
||||
constructObject(s, c, i32Result)
|
||||
result = int(i32Result)
|
||||
|
||||
proc representObject*[T: int8|int16|int32|int64](value: T, ts: TagStyle,
|
||||
c: SerializationContext, tag: TagId): RawYamlStream {.raises: [].} =
|
||||
|
@ -86,9 +88,11 @@ proc representObject*[T: int8|int16|int32|int64](value: T, ts: TagStyle,
|
|||
|
||||
template representObject*(value: int, tagStyle: TagStyle,
|
||||
c: SerializationContext, tag: TagId): RawYamlStream =
|
||||
## calling this will raise a compiler error because ``int`` is not supported
|
||||
{.fatal: "The length of `int` is platform dependent. Use int[8|16|32|64].".}
|
||||
discard
|
||||
## represent an integer of architecture-defined length by casting it to int32.
|
||||
## on 64-bit systems, this may cause a type conversion error.
|
||||
|
||||
# currently, sizeof(int) is at least sizeof(int32).
|
||||
representObject(int32(value), tagStyle, c, tag)
|
||||
|
||||
{.push overflowChecks: on.}
|
||||
proc parseBiggestUInt(s: string): uint64 =
|
||||
|
@ -108,11 +112,11 @@ proc constructObject*[T: uint8|uint16|uint32|uint64](
|
|||
|
||||
template constructObject*(s: var YamlStream, c: ConstructionContext,
|
||||
result: var uint) =
|
||||
## calling this will raise a compiler error because ``uint`` is not
|
||||
## supported
|
||||
{.fatal:
|
||||
"The length of `uint` is platform dependent. Use uint[8|16|32|64].".}
|
||||
discard
|
||||
## represent an unsigned integer of architecture-defined length by loading it
|
||||
## into uint32 and then converting it.
|
||||
var u32Result: uint32
|
||||
constructObject(s, c, u32Result)
|
||||
result= uint(u32Result)
|
||||
|
||||
proc representObject*[T: uint8|uint16|uint32|uint64](value: T, ts: TagStyle,
|
||||
c: SerializationContext, tag: TagId): RawYamlStream {.raises: [].} =
|
||||
|
@ -122,13 +126,11 @@ proc representObject*[T: uint8|uint16|uint32|uint64](value: T, ts: TagStyle,
|
|||
|
||||
template representObject*(value: uint, ts: TagStyle, c: SerializationContext,
|
||||
tag: TagId): RawYamlStream =
|
||||
## calling this will raise a compiler error because ``uint`` is not
|
||||
## supported
|
||||
{.fatal:
|
||||
"The length of `uint` is platform dependent. Use uint[8|16|32|64].".}
|
||||
discard
|
||||
## represent an unsigned integer of architecture-defined length by casting it
|
||||
## to int32. on 64-bit systems, this may cause a type conversion error.
|
||||
representObject(uint32(value), tagStyle, c, tag)
|
||||
|
||||
proc constructObject*[T: float32|float64](
|
||||
proc constructObject*[T: float|float32|float64](
|
||||
s: var YamlStream, c: ConstructionContext, result: var T)
|
||||
{.raises: [YamlConstructionError, YamlStreamError].} =
|
||||
## construct a float value from a YAML scalar
|
||||
|
@ -144,13 +146,7 @@ proc constructObject*[T: float32|float64](
|
|||
raise newException(YamlConstructionError,
|
||||
"Cannot construct to float: " & item.scalarContent)
|
||||
|
||||
template constructObject*(s: var YamlStream, c: ConstructionContext,
|
||||
result: var float) =
|
||||
## calling this will raise a compiler error because ``float`` is not
|
||||
## supported
|
||||
{.fatal: "The length of `float` is platform dependent. Use float[32|64].".}
|
||||
|
||||
proc representObject*[T: float32|float64](value: T, ts: TagStyle,
|
||||
proc representObject*[T: float|float32|float64](value: T, ts: TagStyle,
|
||||
c: SerializationContext, tag: TagId): RawYamlStream {.raises: [].} =
|
||||
## represents a float value as YAML scalar
|
||||
result = iterator(): YamlStreamEvent =
|
||||
|
@ -162,12 +158,6 @@ proc representObject*[T: float32|float64](value: T, ts: TagStyle,
|
|||
else: asString = $value
|
||||
yield scalarEvent(asString, tag, yAnchorNone)
|
||||
|
||||
template representObject*(value: float, tagStyle: TagStyle,
|
||||
c: SerializationContext, tag: TagId): RawYamlStream =
|
||||
## calling this will result in a compiler error because ``float`` is not
|
||||
## supported
|
||||
{.fatal: "The length of `float` is platform dependent. Use float[32|64].".}
|
||||
|
||||
proc yamlTag*(T: typedesc[bool]): TagId {.inline, raises: [].} = yTagBoolean
|
||||
|
||||
proc constructObject*(s: var YamlStream, c: ConstructionContext,
|
||||
|
|
|
@ -25,7 +25,10 @@ type
|
|||
value: string
|
||||
next: ref Node
|
||||
|
||||
BetterInt = int
|
||||
BetterInt = distinct int
|
||||
|
||||
proc `$`(v: BetterInt): string {.borrow.}
|
||||
proc `==`(l, r: BetterInt): bool {.borrow.}
|
||||
|
||||
setTagUriForType(TrafficLight, "!tl")
|
||||
setTagUriForType(Node, "!example.net:Node")
|
||||
|
@ -65,6 +68,31 @@ suite "Serialization":
|
|||
setup:
|
||||
let blockOnly = defineOptions(style=psBlockOnly)
|
||||
|
||||
test "Serialization: Load integer without fixed length":
|
||||
var input = newStringStream("-4247")
|
||||
var result: int
|
||||
load(input, result)
|
||||
assert result == -4247, "result is " & $result
|
||||
|
||||
input = newStringStream($(int64(int32.high) + 1'i64))
|
||||
var gotException = false
|
||||
try: load(input, result)
|
||||
except: gotException = true
|
||||
assert gotException, "Expected exception, got none."
|
||||
|
||||
test "Serialization: Dump integer without fixed length":
|
||||
var input = -4247
|
||||
var output = newStringStream()
|
||||
dump(input, output, tsNone, asTidy, blockOnly)
|
||||
assertStringEqual "%YAML 1.2\n--- \n\"-4247\"", output.data
|
||||
|
||||
when sizeof(int) == sizeof(int64):
|
||||
input = int(int32.high) + 1
|
||||
var gotException = false
|
||||
try: dump(input, output, tsNone, asTidy, blockOnly)
|
||||
except: gotException = true
|
||||
assert gotException, "Expected exception, got none."
|
||||
|
||||
test "Serialization: Load string sequence":
|
||||
let input = newStringStream(" - a\n - b")
|
||||
var result: seq[string]
|
||||
|
@ -330,8 +358,8 @@ next:
|
|||
var result: seq[BetterInt]
|
||||
load(input, result)
|
||||
assert(result.len == 2)
|
||||
assert(result[0] == 2)
|
||||
assert(result[1] == 3)
|
||||
assert(result[0] == 2.BetterInt)
|
||||
assert(result[1] == 3.BetterInt)
|
||||
|
||||
test "Serialization: Custom representObject":
|
||||
let input = @[1.BetterInt, 9998887.BetterInt, 98312.BetterInt]
|
||||
|
|
Loading…
Reference in New Issue