mirror of https://github.com/status-im/NimYAML.git
Made serialization part of yaml. Improved doc.
This commit is contained in:
parent
c6c13eb044
commit
325e3ec18f
|
@ -21,7 +21,6 @@ task serializationTests, "Run serialization tests":
|
|||
task documentation, "Generate documentation":
|
||||
exec "mkdir -p docout"
|
||||
exec r"nim doc2 -o:docout/yaml.html --docSeeSrcUrl:https://github.com/flyx/NimYAML/blob/`git log -n 1 --format=%H` yaml"
|
||||
exec r"nim doc2 -o:docout/serialization.html --docSeeSrcUrl:https://github.com/flyx/NimYAML/blob/`git log -n 1 --format=%H` yaml/serialization.nim"
|
||||
exec r"nim rst2html -o:docout/index.html doc/index.txt"
|
||||
exec "cp doc/docutils.css doc/style.css doc/testing.html doc/processing.svg docout"
|
||||
setCommand "nop"
|
||||
|
|
|
@ -96,7 +96,9 @@
|
|||
<g id="atomics" text-anchor="middle" transform="translate(0 90)">
|
||||
<g id="represent" transform="translate(65 10)">
|
||||
<use xlink:href="#atomic-right-long"/>
|
||||
<text x="80" y="25" font-style="italic">represent</text>
|
||||
<a xlink:href="yaml.html#represent,T,TagStyle,AnchorStyle" target="_top">
|
||||
<text x="80" y="25" font-style="italic">represent</text>
|
||||
</a>
|
||||
</g>
|
||||
|
||||
<g id="serialize" transform="translate(235 10)">
|
||||
|
@ -113,7 +115,9 @@
|
|||
|
||||
<g id="construct" transform="translate(65 120)">
|
||||
<use xlink:href="#atomic-left-long"/>
|
||||
<text x="80" y="35" font-style="italic">construct</text>
|
||||
<a xlink:href="yaml.html#construct,YamlStream,T" target="_top">
|
||||
<text x="80" y="35" font-style="italic">construct</text>
|
||||
</a>
|
||||
</g>
|
||||
|
||||
<g id="compose" transform="translate(235 120)">
|
||||
|
@ -132,22 +136,30 @@
|
|||
<g id="skipping-things" text-anchor="middle" transform="translate(0 50)">
|
||||
<g id="skipping-represent" transform="translate(55 10)">
|
||||
<use xlink:href="#skipping-right"/>
|
||||
<text x="175" y="25" font-weight="bold">represent</text>
|
||||
<a xlink:href="yaml.html#represent,T,TagStyle,AnchorStyle" target="_top">
|
||||
<text x="175" y="25" font-weight="bold">represent</text>
|
||||
</a>
|
||||
</g>
|
||||
<g id="skipping-construct" transform="translate(55 160)">
|
||||
<use xlink:href="#skipping-left"/>
|
||||
<text x="175" y="75" font-weight="bold">construct</text>
|
||||
<a xlink:href="yaml.html#construct,YamlStream,T" target="_top">
|
||||
<text x="175" y="75" font-weight="bold">construct</text>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<g id="whole-lines" text-anchor="middle" transform="translate(0 20)">
|
||||
<g id="dump">
|
||||
<use xlink:href="#whole-right"/>
|
||||
<text x="325" y="25" font-style="italic" font-weight="bold">dump</text>
|
||||
<a xlink:href="yaml.html#dump,K,Stream,PresentationStyle,TagStyle,AnchorStyle,int" target="_top">
|
||||
<text x="325" y="25" font-style="italic" font-weight="bold">dump</text>
|
||||
</a>
|
||||
</g>
|
||||
<g id="load" transform="translate(0 280)">
|
||||
<use xlink:href="#whole-left"/>
|
||||
<text x="325" y="25" font-style="italic" font-weight="bold">load</text>
|
||||
<a xlink:href="yaml.html#load,Stream,K" target="_top">
|
||||
<text x="325" y="25" font-style="italic" font-weight="bold">load</text>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
|
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 7.3 KiB |
|
@ -67,7 +67,7 @@ html {
|
|||
}
|
||||
|
||||
/* necessary for links to scroll to the right position */
|
||||
dt:before {
|
||||
dt a:before {
|
||||
margin-top: -50px;
|
||||
height: 50px;
|
||||
content: ' ';
|
||||
|
|
|
@ -109,7 +109,6 @@ doc.file = """
|
|||
<a href="testing.html">Testing Ground</a>
|
||||
<span>API:</span>
|
||||
<a href="yaml.html">Module yaml</a>
|
||||
<a href="serialization.html">Module yaml.serialization</a>
|
||||
</header>
|
||||
<article id="documentId">
|
||||
<div class="container">
|
||||
|
|
|
@ -1,41 +1,3 @@
|
|||
import "../yaml"
|
||||
import macros, strutils, streams, tables, json, hashes, typetraits
|
||||
export yaml, streams, tables, json
|
||||
|
||||
type
|
||||
TagStyle* = enum
|
||||
tsNone, tsRootOnly, tsAll
|
||||
|
||||
AnchorStyle* = enum
|
||||
asNone, asTidy, asAlways
|
||||
|
||||
RefNodeData* = object
|
||||
p: pointer
|
||||
count: int
|
||||
anchor: AnchorId
|
||||
|
||||
ConstructionContext* = ref object
|
||||
refs: Table[AnchorId, pointer]
|
||||
|
||||
SerializationContext* = ref object
|
||||
refsList: seq[RefNodeData]
|
||||
style: AnchorStyle
|
||||
|
||||
RawYamlStream* = iterator(): YamlStreamEvent {.raises: [].}
|
||||
|
||||
const
|
||||
yTagNimInt8* = 100.TagId
|
||||
yTagNimInt16* = 101.TagId
|
||||
yTagNimInt32* = 102.TagId
|
||||
yTagNimInt64* = 103.TagId
|
||||
yTagNimUInt8* = 104.TagId
|
||||
yTagNimUInt16* = 105.TagId
|
||||
yTagNimUInt32* = 106.TagId
|
||||
yTagNimUInt64* = 107.TagId
|
||||
yTagNimFloat32* = 108.TagId
|
||||
yTagNimFloat64* = 109.TagId
|
||||
yTagNimChar* = 110.TagId
|
||||
|
||||
proc initRefNodeData(p: pointer): RefNodeData =
|
||||
result.p = p
|
||||
result.count = 1
|
||||
|
@ -98,12 +60,16 @@ template presentTag(t: typedesc, ts: TagStyle): TagId =
|
|||
if ts == tsNone: yTagQuestionMark else: yamlTag(t)
|
||||
|
||||
proc lazyLoadTag*(uri: string): TagId {.inline, raises: [].} =
|
||||
## Internal function. Do not call explicitly.
|
||||
try:
|
||||
result = serializationTagLibrary.tags[uri]
|
||||
except KeyError:
|
||||
result = serializationTagLibrary.registerUri(uri)
|
||||
|
||||
macro serializable*(types: stmt): stmt =
|
||||
## Macro for customizing serialization of user-defined types.
|
||||
## Currently does not provide more features than just using the standard
|
||||
## serialization procs. This will change in the future.
|
||||
assert types.kind == nnkTypeSection
|
||||
result = newStmtList(types)
|
||||
for typedef in types.children:
|
||||
|
@ -281,6 +247,7 @@ macro serializable*(types: stmt): stmt =
|
|||
result.add(representProc)
|
||||
|
||||
proc safeTagUri*(id: TagId): string {.raises: [].} =
|
||||
## Internal function. Do not call explicitly.
|
||||
try:
|
||||
let uri = serializationTagLibrary.uri(id)
|
||||
if uri.len > 0 and uri[0] == '!':
|
||||
|
@ -744,6 +711,7 @@ proc representObject*[O](value: ref O, ts: TagStyle, c: SerializationContext):
|
|||
|
||||
proc construct*[T](s: var YamlStream, target: var T)
|
||||
{.raises: [YamlConstructionError, YamlStreamError].} =
|
||||
## Construct a Nim value from a YAML stream.
|
||||
var
|
||||
context = newConstructionContext()
|
||||
try:
|
||||
|
@ -763,6 +731,7 @@ proc construct*[T](s: var YamlStream, target: var T)
|
|||
|
||||
proc load*[K](input: Stream, target: var K)
|
||||
{.raises: [YamlConstructionError, IOError, YamlParserError].} =
|
||||
## Load a Nim value from a YAML character stream.
|
||||
var
|
||||
parser = newYamlParser(serializationTagLibrary)
|
||||
events = parser.parse(input)
|
||||
|
@ -809,6 +778,7 @@ proc setAliasAnchor(a: var AnchorId, q: var seq[RefNodeData]) {.inline.} =
|
|||
|
||||
proc represent*[T](value: T, ts: TagStyle = tsRootOnly,
|
||||
a: AnchorStyle = asTidy): YamlStream {.raises: [].} =
|
||||
## Represent a Nim value as ``YamlStream``.
|
||||
var
|
||||
context = newSerializationContext(a)
|
||||
objStream = iterator(): YamlStreamEvent =
|
||||
|
@ -850,6 +820,7 @@ proc dump*[K](value: K, target: Stream, style: PresentationStyle = psDefault,
|
|||
tagStyle: TagStyle = tsRootOnly,
|
||||
anchorStyle: AnchorStyle = asTidy, indentationStep: int = 2)
|
||||
{.raises: [YamlPresenterJsonError, YamlPresenterOutputError].} =
|
||||
## Dump a Nim value as YAML character stream.
|
||||
var events = represent(value, if style == psCanonical: tsAll else: tagStyle,
|
||||
if style == psJson: asNone else: anchorStyle)
|
||||
try:
|
|
@ -1,4 +1,4 @@
|
|||
import "../yaml/serialization"
|
||||
import "../yaml"
|
||||
import unittest
|
||||
|
||||
type
|
||||
|
|
79
yaml.nim
79
yaml.nim
|
@ -16,7 +16,8 @@
|
|||
## automatically supported. While JSON is less readable than YAML,
|
||||
## this enhances interoperability with other languages.
|
||||
|
||||
import streams, unicode, lexbase, tables, strutils, json, hashes, queues, macros
|
||||
import streams, unicode, lexbase, tables, strutils, json, hashes, queues,
|
||||
macros, typetraits
|
||||
export streams, tables, json
|
||||
|
||||
when defined(yamlDebug):
|
||||
|
@ -178,6 +179,51 @@ type
|
|||
## flow style at all.
|
||||
psMinimal, psCanonical, psDefault, psJson, psBlockOnly
|
||||
|
||||
TagStyle* = enum
|
||||
## Whether object should be serialized with explicit tags.
|
||||
##
|
||||
## - ``tsNone``: No tags will be outputted unless necessary.
|
||||
## - ``tsRootOnly``: A tag will only be outputted for the root tag and
|
||||
## where necessary.
|
||||
## - ``tsAll``: Tags will be outputted for every object.
|
||||
tsNone, tsRootOnly, tsAll
|
||||
|
||||
AnchorStyle* = enum
|
||||
## How ref object should be serialized.
|
||||
##
|
||||
## - ``asNone``: No anchors will be outputted. Values present at
|
||||
## multiple places in the content that should be
|
||||
## serialized will be fully serialized at every occurence.
|
||||
## If the content is cyclic, this will lead to an
|
||||
## endless loop!
|
||||
## - ``asTidy``: Anchors will only be generated for objects that
|
||||
## actually occur more than once in the content to be
|
||||
## serialized. This is a bit slower and needs more memory
|
||||
## than ``asAlways``.
|
||||
## - ``asAlways``: Achors will be generated for every ref object in the
|
||||
## content to be serialized, regardless of whether the
|
||||
## object is referenced again afterwards
|
||||
asNone, asTidy, asAlways
|
||||
|
||||
RefNodeData = object
|
||||
p: pointer
|
||||
count: int
|
||||
anchor: AnchorId
|
||||
|
||||
ConstructionContext* = ref object
|
||||
## Context information for the process of constructing Nim values from
|
||||
## YAML.
|
||||
refs: Table[AnchorId, pointer]
|
||||
|
||||
SerializationContext* = ref object
|
||||
## Context information for the process of serializing YAML from Nim
|
||||
## values.
|
||||
refsList: seq[RefNodeData]
|
||||
style: AnchorStyle
|
||||
|
||||
RawYamlStream* = iterator(): YamlStreamEvent {.raises: [].} ## \
|
||||
## Stream of ``YamlStreamEvent``s returned by ``representObject`` procs.
|
||||
|
||||
YamlLoadingError* = object of Exception
|
||||
## Base class for all exceptions that may be raised during the process
|
||||
## of loading a YAML character stream.
|
||||
|
@ -296,6 +342,18 @@ const
|
|||
## yielded when no anchor was defined for a YAML node
|
||||
|
||||
yamlTagRepositoryPrefix* = "tag:yaml.org,2002:"
|
||||
|
||||
yTagNimInt8* = 100.TagId ## tag for Nim's ``int8``
|
||||
yTagNimInt16* = 101.TagId ## tag for Nim's ``int16``
|
||||
yTagNimInt32* = 102.TagId ## tag for Nim's ``int32``
|
||||
yTagNimInt64* = 103.TagId ## tag for Nim's ``int64``
|
||||
yTagNimUInt8* = 104.TagId ## tag for Nim's ``uint8``
|
||||
yTagNimUInt16* = 105.TagId ## tag for Nim's ``uint16``
|
||||
yTagNimUInt32* = 106.TagId ## tag for Nim's ``uint32``
|
||||
yTagNimUInt64* = 107.TagId ## tag for Nim's ``uint64``
|
||||
yTagNimFloat32* = 108.TagId ## tag for Nim's ``float32``
|
||||
yTagNimFloat64* = 109.TagId ## tag for Nim's ``float64``
|
||||
yTagNimChar* = 110.TagId ## tag for Nim's ``char``
|
||||
|
||||
# interface
|
||||
|
||||
|
@ -330,11 +388,25 @@ proc hash*(id: AnchorId): Hash {.borrow.}
|
|||
|
||||
proc initYamlStream*(backend: iterator(): YamlStreamEvent):
|
||||
YamlStream {.raises: [].}
|
||||
## Creates a new ``YamlStream`` that uses the given iterator as backend.
|
||||
proc next*(s: var YamlStream): YamlStreamEvent {.raises: [YamlStreamError].}
|
||||
## Get the next item of the stream. Requires ``finished(s) == true``.
|
||||
## If the backend yields an exception, that exception will be encapsulated
|
||||
## into a ``YamlStreamError``, which will be raised.
|
||||
proc peek*(s: var YamlStream): YamlStreamEvent {.raises: [YamlStreamError].}
|
||||
## Get the next item of the stream without advancing the stream.
|
||||
## Requires ``finished(s) == true``. Handles exceptions of the backend like
|
||||
## ``next()``.
|
||||
proc `peek=`*(s: var YamlStream, value: YamlStreamEvent) {.raises: [].}
|
||||
## Set the next item of the stream. Will replace a previously peeked item,
|
||||
## if one exists.
|
||||
proc finished*(s: var YamlStream): bool {.raises: [YamlStreamError].}
|
||||
iterator items*(s: var YamlStream): YamlStreamEvent {.raises: [YamlStreamError].} =
|
||||
## ``true`` if no more items are available in the stream. Handles exceptions
|
||||
## of the backend like ``next()``.
|
||||
iterator items*(s: var YamlStream): YamlStreamEvent
|
||||
{.raises: [YamlStreamError].} =
|
||||
## Iterate over all items of the stream. You may not use ``peek()`` on the
|
||||
## stream while iterating.
|
||||
if s.peeked:
|
||||
s.peeked = false
|
||||
yield s.cached
|
||||
|
@ -463,4 +535,5 @@ include private.json
|
|||
include private.presenter
|
||||
include private.hints
|
||||
include private.fastparse
|
||||
include private.streams
|
||||
include private.streams
|
||||
include private.serialization
|
Loading…
Reference in New Issue