mirror of https://github.com/status-im/NimYAML.git
Implemented basic serialization
* added serialize() procs for some basic types * extended make_serializable to generate serialize() proc
This commit is contained in:
parent
dc1a3c0fe2
commit
9ff93efb11
|
@ -23,6 +23,13 @@ suite "Serialization":
|
||||||
assert result[0] == "a"
|
assert result[0] == "a"
|
||||||
assert result[1] == "b"
|
assert result[1] == "b"
|
||||||
|
|
||||||
|
test "Serialize string sequence":
|
||||||
|
var input = @["a", "b"]
|
||||||
|
var output = newStringStream()
|
||||||
|
dump(wrapWithDocument(serialize(input)), output, coreTagLibrary(),
|
||||||
|
yDumpBlockOnly)
|
||||||
|
assert output.data == "%YAML 1.2\n--- \n- a\n- b"
|
||||||
|
|
||||||
test "Load Table[int, string]":
|
test "Load Table[int, string]":
|
||||||
let input = newStringStream("23: dreiundzwanzig\n42: zweiundvierzig")
|
let input = newStringStream("23: dreiundzwanzig\n42: zweiundvierzig")
|
||||||
var
|
var
|
||||||
|
@ -35,6 +42,15 @@ suite "Serialization":
|
||||||
assert result[23] == "dreiundzwanzig"
|
assert result[23] == "dreiundzwanzig"
|
||||||
assert result[42] == "zweiundvierzig"
|
assert result[42] == "zweiundvierzig"
|
||||||
|
|
||||||
|
test "Serialize Table[int, string]":
|
||||||
|
var input = initTable[int, string]()
|
||||||
|
input[23] = "dreiundzwanzig"
|
||||||
|
input[42] = "zweiundvierzig"
|
||||||
|
var output = newStringStream()
|
||||||
|
dump(wrapWithDocument(serialize(input)), output, coreTagLibrary(),
|
||||||
|
yDumpBlockOnly)
|
||||||
|
assert output.data == "%YAML 1.2\n--- \n23: dreiundzwanzig\n42: zweiundvierzig"
|
||||||
|
|
||||||
test "Load Sequences in Sequence":
|
test "Load Sequences in Sequence":
|
||||||
let input = newStringStream(" - [1, 2, 3]\n - [4, 5]\n - [6]")
|
let input = newStringStream(" - [1, 2, 3]\n - [4, 5]\n - [6]")
|
||||||
var
|
var
|
||||||
|
@ -48,6 +64,13 @@ suite "Serialization":
|
||||||
assert result[1] == @[4, 5]
|
assert result[1] == @[4, 5]
|
||||||
assert result[2] == @[6]
|
assert result[2] == @[6]
|
||||||
|
|
||||||
|
test "Serialize Sequences in Sequence":
|
||||||
|
let input = @[@[1, 2, 3], @[4, 5], @[6]]
|
||||||
|
var output = newStringStream()
|
||||||
|
dump(wrapWithDocument(serialize(input)), output, coreTagLibrary(),
|
||||||
|
yDumpDefault)
|
||||||
|
assert output.data == "%YAML 1.2\n--- \n- [1, 2, 3]\n- [4, 5]\n- [6]"
|
||||||
|
|
||||||
test "Load custom object":
|
test "Load custom object":
|
||||||
let input = newStringStream("firstname: Peter\nsurname: Pan\nage: 12")
|
let input = newStringStream("firstname: Peter\nsurname: Pan\nage: 12")
|
||||||
var
|
var
|
||||||
|
@ -59,3 +82,10 @@ suite "Serialization":
|
||||||
assert result.firstname == "Peter"
|
assert result.firstname == "Peter"
|
||||||
assert result.surname == "Pan"
|
assert result.surname == "Pan"
|
||||||
assert result.age == 12
|
assert result.age == 12
|
||||||
|
|
||||||
|
test "Serialize custom object":
|
||||||
|
let input = Person(firstname: "Peter", surname: "Pan", age: 12)
|
||||||
|
var output = newStringStream()
|
||||||
|
dump(wrapWithDocument(serialize(input)), output, coreTagLibrary(),
|
||||||
|
yDumpBlockOnly)
|
||||||
|
assert output.data == "%YAML 1.2\n--- \nfirstname: Peter\nsurname: Pan\nage: 12"
|
|
@ -25,10 +25,12 @@ macro make_serializable*(types: stmt): stmt =
|
||||||
assert objectTy[1].kind == nnkEmpty
|
assert objectTy[1].kind == nnkEmpty
|
||||||
let recList = objectTy[2]
|
let recList = objectTy[2]
|
||||||
assert recList.kind == nnkRecList
|
assert recList.kind == nnkRecList
|
||||||
|
|
||||||
|
# construct()
|
||||||
|
|
||||||
var constructProc = newProc(newIdentNode("construct"), [
|
var constructProc = newProc(newIdentNode("construct"), [
|
||||||
newEmptyNode(),
|
newEmptyNode(),
|
||||||
newIdentDefs(newIdentNode("s"), newNimNode(nnkVarTy).add(
|
newIdentDefs(newIdentNode("s"), newIdentNode("YamlStream")),
|
||||||
newIdentNode("YamlStream"))),
|
|
||||||
newIdentDefs(newIdentNode("result"),
|
newIdentDefs(newIdentNode("result"),
|
||||||
newNimNode(nnkVarTy).add(tIdent))])
|
newNimNode(nnkVarTy).add(tIdent))])
|
||||||
var impl = quote do:
|
var impl = quote do:
|
||||||
|
@ -64,13 +66,58 @@ macro make_serializable*(types: stmt): stmt =
|
||||||
constructProc[6] = impl
|
constructProc[6] = impl
|
||||||
result.add(constructProc)
|
result.add(constructProc)
|
||||||
|
|
||||||
|
# serialize()
|
||||||
|
|
||||||
|
var serializeProc = newProc(newIdentNode("serialize"), [
|
||||||
|
newIdentNode("YamlStream"),
|
||||||
|
newIdentDefs(newIdentNode("value"), tIdent),
|
||||||
|
newIdentDefs(newIdentNode("verboseTags"), newIdentNode("bool"),
|
||||||
|
newIdentNode("false"))])
|
||||||
|
var iterBody = quote do:
|
||||||
|
yield YamlStreamEvent(kind: yamlStartMap,
|
||||||
|
mapTag: yTagQuestionMark,
|
||||||
|
mapAnchor: yAnchorNone)
|
||||||
|
yield YamlStreamEvent(kind: yamlEndMap)
|
||||||
|
|
||||||
|
var i = 1
|
||||||
|
for field in objectFields(recList):
|
||||||
|
let
|
||||||
|
fieldIterIdent = newIdentNode($field.name & "Events")
|
||||||
|
fieldNameString = newStrLitNode($field.name)
|
||||||
|
iterbody.insert(i, quote do:
|
||||||
|
yield YamlStreamEvent(kind: yamlScalar,
|
||||||
|
scalarTag: yTagQuestionMark,
|
||||||
|
scalarAnchor: yAnchorNone,
|
||||||
|
scalarContent: `fieldNameString`)
|
||||||
|
)
|
||||||
|
iterbody.insert(i + 1, newVarStmt(fieldIterIdent,
|
||||||
|
newCall("serialize", newDotExpr(newIdentNode("value"),
|
||||||
|
field.name), newIdentNode("verboseTags"))))
|
||||||
|
iterbody.insert(i + 2, quote do:
|
||||||
|
for event in `fieldIterIdent`():
|
||||||
|
yield event
|
||||||
|
)
|
||||||
|
i += 3
|
||||||
|
impl = newStmtList(newAssignment(newIdentNode("result"), newProc(
|
||||||
|
newEmptyNode(), [newIdentNode("YamlStreamEvent")], iterBody,
|
||||||
|
nnkIteratorDef)))
|
||||||
|
serializeProc[6] = impl
|
||||||
|
result.add(serializeProc)
|
||||||
|
|
||||||
proc prepend*(event: YamlStreamEvent, s: YamlStream): YamlStream =
|
proc prepend*(event: YamlStreamEvent, s: YamlStream): YamlStream =
|
||||||
result = iterator(): YamlStreamEvent =
|
result = iterator(): YamlStreamEvent =
|
||||||
yield event
|
yield event
|
||||||
for e in s():
|
for e in s():
|
||||||
yield e
|
yield e
|
||||||
|
|
||||||
proc construct*(s: var YamlStream, result: var string) =
|
proc wrapWithDocument*(s: YamlStream): YamlStream =
|
||||||
|
result = iterator(): YamlStreamEvent =
|
||||||
|
yield YamlStreamEvent(kind: yamlStartDocument)
|
||||||
|
for event in s():
|
||||||
|
yield event
|
||||||
|
yield YamlStreamEvent(kind: yamlEndDocument)
|
||||||
|
|
||||||
|
proc construct*(s: YamlStream, result: var string) =
|
||||||
let item = s()
|
let item = s()
|
||||||
if finished(s) or item.kind != yamlScalar:
|
if finished(s) or item.kind != yamlScalar:
|
||||||
raise newException(ValueError, "Construction error!")
|
raise newException(ValueError, "Construction error!")
|
||||||
|
@ -78,7 +125,13 @@ proc construct*(s: var YamlStream, result: var string) =
|
||||||
raise newException(ValueError, "Wrong tag for string.")
|
raise newException(ValueError, "Wrong tag for string.")
|
||||||
result = item.scalarContent
|
result = item.scalarContent
|
||||||
|
|
||||||
proc construct*(s: var YamlStream, result: var int) =
|
proc serialize*(value: string, verboseTags: bool = false): YamlStream =
|
||||||
|
result = iterator(): YamlStreamEvent =
|
||||||
|
yield YamlStreamEvent(kind: yamlScalar, scalarTag:
|
||||||
|
if verboseTags: yTagString else: yTagQuestionMark,
|
||||||
|
scalarAnchor: yAnchorNone, scalarContent: value)
|
||||||
|
|
||||||
|
proc construct*(s: YamlStream, result: var int) =
|
||||||
let item = s()
|
let item = s()
|
||||||
if finished(s) or item.kind != yamlScalar:
|
if finished(s) or item.kind != yamlScalar:
|
||||||
raise newException(ValueError, "Construction error!")
|
raise newException(ValueError, "Construction error!")
|
||||||
|
@ -87,7 +140,13 @@ proc construct*(s: var YamlStream, result: var int) =
|
||||||
raise newException(ValueError, "Wrong scalar type for int.")
|
raise newException(ValueError, "Wrong scalar type for int.")
|
||||||
result = parseInt(item.scalarContent)
|
result = parseInt(item.scalarContent)
|
||||||
|
|
||||||
proc contruct*(s: var YamlStream, result: var int64) =
|
proc serialize*(value: int, verboseTags: bool = false): YamlStream =
|
||||||
|
result = iterator(): YamlStreamEvent =
|
||||||
|
yield YamlStreamEvent(kind: yamlScalar, scalarTag:
|
||||||
|
if verboseTags: yTagInteger else: yTagQuestionMark,
|
||||||
|
scalarAnchor: yAnchorNone, scalarContent: $value)
|
||||||
|
|
||||||
|
proc contruct*(s: YamlStream, result: var int64) =
|
||||||
let item = s()
|
let item = s()
|
||||||
if finished(s) or item.kind != yamlScalar:
|
if finished(s) or item.kind != yamlScalar:
|
||||||
raise newException(ValueError, "Construction error!")
|
raise newException(ValueError, "Construction error!")
|
||||||
|
@ -96,7 +155,13 @@ proc contruct*(s: var YamlStream, result: var int64) =
|
||||||
raise newException(ValueError, "Wrong scalar type for int64.")
|
raise newException(ValueError, "Wrong scalar type for int64.")
|
||||||
result = parseBiggestInt(item.scalarContent)
|
result = parseBiggestInt(item.scalarContent)
|
||||||
|
|
||||||
proc construct*(s: var YamlStream, result: var float) =
|
proc serialize*(value: int64, verboseTags: bool = false): YamlStream =
|
||||||
|
result = iterator(): YamlStreamEvent =
|
||||||
|
yield YamlStreamEvent(kind: yamlScalar, scalarTag:
|
||||||
|
if verboseTags: yTagInteger else: yTagQuestionMark,
|
||||||
|
scalarAnchor: yAnchorNone, scalarContent: $value)
|
||||||
|
|
||||||
|
proc construct*(s: YamlStream, result: var float) =
|
||||||
let item = s()
|
let item = s()
|
||||||
if finished(s) or item.kind != yamlScalar:
|
if finished(s) or item.kind != yamlScalar:
|
||||||
raise newException(ValueError, "Construction error!")
|
raise newException(ValueError, "Construction error!")
|
||||||
|
@ -115,7 +180,19 @@ proc construct*(s: var YamlStream, result: var float) =
|
||||||
else:
|
else:
|
||||||
raise newException(ValueError, "Wrong scalar type for float.")
|
raise newException(ValueError, "Wrong scalar type for float.")
|
||||||
|
|
||||||
proc construct*(s: var YamlStream, result: var bool) =
|
proc serialize*(value: float, verboseTags: bool = false): YamlStream =
|
||||||
|
result = iterator(): YamlStreamEvent =
|
||||||
|
var asString = case value
|
||||||
|
of Inf: ".inf"
|
||||||
|
of NegInf: "-.inf"
|
||||||
|
of NaN: ".nan"
|
||||||
|
else: $value
|
||||||
|
|
||||||
|
yield YamlStreamEvent(kind: yamlScalar, scalarTag:
|
||||||
|
if verboseTags: yTagFloat else: yTagQuestionMark,
|
||||||
|
scalarAnchor: yAnchorNone, scalarContent: asString)
|
||||||
|
|
||||||
|
proc construct*(s: YamlStream, result: var bool) =
|
||||||
let item = s()
|
let item = s()
|
||||||
if finished(s) or item.kind != yamlScalar:
|
if finished(s) or item.kind != yamlScalar:
|
||||||
raise newException(ValueError, "Construction error!")
|
raise newException(ValueError, "Construction error!")
|
||||||
|
@ -129,7 +206,14 @@ proc construct*(s: var YamlStream, result: var bool) =
|
||||||
else:
|
else:
|
||||||
raise newException(ValueError, "Wrong scalar type for bool.")
|
raise newException(ValueError, "Wrong scalar type for bool.")
|
||||||
|
|
||||||
proc construct*[T](s: var YamlStream, result: var seq[T]) =
|
proc serialize*(value: bool, verboseTags: bool = false): YamlStream =
|
||||||
|
result = iterator(): YamlStreamEvent =
|
||||||
|
yield YamlStreamEvent(kind: yamlScalar, scalarTag:
|
||||||
|
if verboseTags: yTagBoolean else: yTagQuestionMark,
|
||||||
|
scalarAnchor: yAnchorNone, scalarContent:
|
||||||
|
if value: "y" else: "n")
|
||||||
|
|
||||||
|
proc construct*[T](s: YamlStream, result: var seq[T]) =
|
||||||
var event = s()
|
var event = s()
|
||||||
if finished(s) or event.kind != yamlStartSequence:
|
if finished(s) or event.kind != yamlStartSequence:
|
||||||
raise newException(ValueError, "Construction error!")
|
raise newException(ValueError, "Construction error!")
|
||||||
|
@ -149,7 +233,17 @@ proc construct*[T](s: var YamlStream, result: var seq[T]) =
|
||||||
if finished(s):
|
if finished(s):
|
||||||
raise newException(ValueError, "Construction error!")
|
raise newException(ValueError, "Construction error!")
|
||||||
|
|
||||||
proc construct*[K, V](s: var YamlStream, result: var Table[K, V]) =
|
proc serialize*[T](value: seq[T], verboseTags: bool = false): YamlStream =
|
||||||
|
result = iterator(): YamlStreamEvent =
|
||||||
|
yield YamlStreamEvent(kind: yamlStartSequence, seqTag: yTagQuestionMark,
|
||||||
|
seqAnchor: yAnchorNone)
|
||||||
|
for item in value:
|
||||||
|
var events = serialize(item, verboseTags)
|
||||||
|
for event in events():
|
||||||
|
yield event
|
||||||
|
yield YamlStreamEvent(kind: yamlEndSequence)
|
||||||
|
|
||||||
|
proc construct*[K, V](s: YamlStream, result: var Table[K, V]) =
|
||||||
var event = s()
|
var event = s()
|
||||||
if finished(s) or event.kind != yamlStartMap:
|
if finished(s) or event.kind != yamlStartMap:
|
||||||
raise newException(ValueError, "Construction error!")
|
raise newException(ValueError, "Construction error!")
|
||||||
|
@ -170,3 +264,17 @@ proc construct*[K, V](s: var YamlStream, result: var Table[K, V]) =
|
||||||
event = s()
|
event = s()
|
||||||
if finished(s):
|
if finished(s):
|
||||||
raise newException(ValueError, "Construction error!")
|
raise newException(ValueError, "Construction error!")
|
||||||
|
|
||||||
|
proc serialize*[K, V](value: Table[K, V],
|
||||||
|
verboseTags: bool = false): YamlStream =
|
||||||
|
result = iterator(): YamlStreamEvent =
|
||||||
|
yield YamlStreamEvent(kind: yamlStartMap, mapTag: yTagQuestionMark,
|
||||||
|
mapAnchor: yAnchorNone)
|
||||||
|
for key, value in value.pairs:
|
||||||
|
var events = serialize(key, verboseTags)
|
||||||
|
for event in events():
|
||||||
|
yield event
|
||||||
|
events = serialize(value, verboseTags)
|
||||||
|
for event in events():
|
||||||
|
yield event
|
||||||
|
yield YamlStreamEvent(kind: yamlEndMap)
|
Loading…
Reference in New Issue