mirror of https://github.com/status-im/NimYAML.git
Presenter: Let user decide about newline style
* Added PresentationOptions object; merged PresentationStyle, indentationStep and NewLineStyle in it * Updated signatures of relevant procs * Implemented user-defined newline style in presenter
This commit is contained in:
parent
349cb19912
commit
46913867e2
|
@ -189,16 +189,16 @@ proc serialize*(doc: YamlDocument, tagLib: TagLibrary, a: AnchorStyle = asTidy):
|
|||
result = initYamlStream(backend)
|
||||
|
||||
proc dumpDOM*(doc: YamlDocument, target: Stream,
|
||||
style: PresentationStyle = psDefault,
|
||||
anchorStyle: AnchorStyle = asTidy, indentationStep: int = 2)
|
||||
anchorStyle: AnchorStyle = asTidy,
|
||||
options: PresentationOptions = defaultPresentationOptions)
|
||||
{.raises: [YamlPresenterJsonError, YamlPresenterOutputError].} =
|
||||
## Dump a YamlDocument as YAML character stream.
|
||||
var
|
||||
tagLib = initExtendedTagLibrary()
|
||||
events = serialize(doc, tagLib,
|
||||
if style == psJson: asNone else: anchorStyle)
|
||||
if options.style == psJson: asNone else: anchorStyle)
|
||||
try:
|
||||
present(events, target, tagLib, style, indentationStep)
|
||||
present(events, target, tagLib, options)
|
||||
except YamlStreamError:
|
||||
# serializing object does not raise any errors, so we can ignore this
|
||||
assert false, "Can never happen"
|
|
@ -16,6 +16,12 @@ type
|
|||
ScalarStyle = enum
|
||||
sLiteral, sFolded, sPlain, sDoubleQuoted
|
||||
|
||||
proc defineOptions*(style: PresentationStyle = psDefault,
|
||||
indentationStep: int = 2, newlines:
|
||||
NewLineStyle = nlOSDefault): PresentationOptions =
|
||||
result = PresentationOptions(style: style, indentationStep: indentationStep,
|
||||
newlines: newlines)
|
||||
|
||||
proc inspect(scalar: string, indentation: int,
|
||||
words, lines: var seq[tuple[start, finish: int]]):
|
||||
ScalarStyle {.raises: [].} =
|
||||
|
@ -89,7 +95,8 @@ proc inspect(scalar: string, indentation: int,
|
|||
elif canUsePlain: result = sPlain
|
||||
else: result = sDoubleQuoted
|
||||
|
||||
proc writeDoubleQuoted(scalar: string, s: Stream, indentation: int)
|
||||
proc writeDoubleQuoted(scalar: string, s: Stream, indentation: int,
|
||||
newline: string)
|
||||
{.raises: [YamlPresenterOutputError].} =
|
||||
var curPos = indentation
|
||||
try:
|
||||
|
@ -97,7 +104,8 @@ proc writeDoubleQuoted(scalar: string, s: Stream, indentation: int)
|
|||
curPos.inc()
|
||||
for c in scalar:
|
||||
if curPos == 79:
|
||||
s.write("\\\l")
|
||||
s.write('\\')
|
||||
s.write(newline)
|
||||
s.write(repeat(' ', indentation))
|
||||
curPos = indentation
|
||||
if c == ' ':
|
||||
|
@ -155,14 +163,14 @@ proc writeDoubleQuotedJson(scalar: string, s: Stream)
|
|||
raise e
|
||||
|
||||
proc writeLiteral(scalar: string, indentation, indentStep: int, s: Stream,
|
||||
lines: seq[tuple[start, finish: int]])
|
||||
lines: seq[tuple[start, finish: int]], newline: string)
|
||||
{.raises: [YamlPresenterOutputError].} =
|
||||
try:
|
||||
s.write('|')
|
||||
if scalar[^1] != '\l': s.write('-')
|
||||
if scalar[0] in [' ', '\t']: s.write($indentStep)
|
||||
for line in lines:
|
||||
s.write('\l')
|
||||
s.write(newline)
|
||||
s.write(repeat(' ', indentation + indentStep))
|
||||
if line.finish >= line.start:
|
||||
s.write(scalar[line.start .. line.finish])
|
||||
|
@ -173,18 +181,18 @@ proc writeLiteral(scalar: string, indentation, indentStep: int, s: Stream,
|
|||
raise e
|
||||
|
||||
proc writeFolded(scalar: string, indentation, indentStep: int, s: Stream,
|
||||
words: seq[tuple[start, finish: int]])
|
||||
words: seq[tuple[start, finish: int]], newline: string)
|
||||
{.raises: [YamlPresenterOutputError].} =
|
||||
try:
|
||||
s.write("|-")
|
||||
var curPos = 80
|
||||
for word in words:
|
||||
if word.start > 0 and scalar[word.start - 1] == '\l':
|
||||
s.write("\l\l")
|
||||
s.write(newline & newline)
|
||||
s.write(repeat(' ', indentation + indentStep))
|
||||
curPos = indentation + indentStep
|
||||
elif curPos + (word.finish - word.start) > 80:
|
||||
s.write('\l')
|
||||
s.write(newline)
|
||||
s.write(repeat(' ', indentation + indentStep))
|
||||
curPos = indentation + indentStep
|
||||
else:
|
||||
|
@ -207,12 +215,12 @@ template safeWrite(s: string or char) {.dirty.} =
|
|||
raise e
|
||||
|
||||
proc startItem(target: Stream, style: PresentationStyle, indentation: int,
|
||||
state: var DumperState, isObject: bool)
|
||||
state: var DumperState, isObject: bool, newline: string)
|
||||
{.raises: [YamlPresenterOutputError].} =
|
||||
try:
|
||||
case state
|
||||
of dBlockMapValue:
|
||||
target.write('\l')
|
||||
target.write(newline)
|
||||
target.write(repeat(' ', indentation))
|
||||
if isObject or style == psCanonical:
|
||||
target.write("? ")
|
||||
|
@ -222,7 +230,7 @@ proc startItem(target: Stream, style: PresentationStyle, indentation: int,
|
|||
of dBlockInlineMap:
|
||||
state = dBlockImplicitMapKey
|
||||
of dBlockExplicitMapKey:
|
||||
target.write('\l')
|
||||
target.write(newline)
|
||||
target.write(repeat(' ', indentation))
|
||||
target.write(": ")
|
||||
state = dBlockMapValue
|
||||
|
@ -231,14 +239,14 @@ proc startItem(target: Stream, style: PresentationStyle, indentation: int,
|
|||
state = dBlockMapValue
|
||||
of dFlowExplicitMapKey:
|
||||
if style != psMinimal:
|
||||
target.write('\l')
|
||||
target.write(newline)
|
||||
target.write(repeat(' ', indentation))
|
||||
target.write(": ")
|
||||
state = dFlowMapValue
|
||||
of dFlowMapValue:
|
||||
if (isObject and style != psMinimal) or
|
||||
style in [psJson, psCanonical]:
|
||||
target.write(",\l" & repeat(' ', indentation))
|
||||
target.write(',' & newline & repeat(' ', indentation))
|
||||
if style == psJson:
|
||||
state = dFlowImplicitMapKey
|
||||
else:
|
||||
|
@ -253,7 +261,7 @@ proc startItem(target: Stream, style: PresentationStyle, indentation: int,
|
|||
of dFlowMapStart:
|
||||
if (isObject and style != psMinimal) or
|
||||
style in [psJson, psCanonical]:
|
||||
target.write("\l" & repeat(' ', indentation))
|
||||
target.write(newline & repeat(' ', indentation))
|
||||
if style == psJson:
|
||||
state = dFlowImplicitMapKey
|
||||
else:
|
||||
|
@ -265,7 +273,7 @@ proc startItem(target: Stream, style: PresentationStyle, indentation: int,
|
|||
target.write(": ")
|
||||
state = dFlowMapValue
|
||||
of dBlockSequenceItem:
|
||||
target.write('\l')
|
||||
target.write(newline)
|
||||
target.write(repeat(' ', indentation))
|
||||
target.write("- ")
|
||||
of dFlowSequenceStart:
|
||||
|
@ -273,7 +281,7 @@ proc startItem(target: Stream, style: PresentationStyle, indentation: int,
|
|||
of psMinimal, psDefault:
|
||||
discard
|
||||
of psCanonical, psJson:
|
||||
target.write('\l')
|
||||
target.write(newline)
|
||||
target.write(repeat(' ', indentation))
|
||||
of psBlockOnly:
|
||||
discard # can never happen
|
||||
|
@ -283,7 +291,7 @@ proc startItem(target: Stream, style: PresentationStyle, indentation: int,
|
|||
of psMinimal, psDefault:
|
||||
target.write(", ")
|
||||
of psCanonical, psJson:
|
||||
target.write(",\l")
|
||||
target.write(',' & newline)
|
||||
target.write(repeat(' ', indentation))
|
||||
of psBlockOnly:
|
||||
discard # can never happen
|
||||
|
@ -327,24 +335,24 @@ proc writeTagAndAnchor(target: Stream, tag: TagId, tagLib: TagLibrary,
|
|||
raise e
|
||||
|
||||
proc present*(s: var YamlStream, target: Stream, tagLib: TagLibrary,
|
||||
style: PresentationStyle = psDefault,
|
||||
indentationStep: int = 2) =
|
||||
options: PresentationOptions = defaultPresentationOptions) =
|
||||
var
|
||||
indentation = 0
|
||||
levels = newSeq[DumperState]()
|
||||
cached = initQueue[YamlStreamEvent]()
|
||||
|
||||
let newline = if options.newlines == nlLF: "\l"
|
||||
elif options.newlines == nlCRLF: "\c\l" else: "\n"
|
||||
while cached.len > 0 or not s.finished():
|
||||
let item = if cached.len > 0: cached.dequeue else: s.next()
|
||||
case item.kind
|
||||
of yamlStartDocument:
|
||||
if style != psJson:
|
||||
if options.style != psJson:
|
||||
# TODO: tag directives
|
||||
try:
|
||||
target.write("%YAML 1.2\l")
|
||||
target.write("%YAML 1.2" & newline)
|
||||
if tagLib.secondaryPrefix != yamlTagRepositoryPrefix:
|
||||
target.write("%TAG !! " &
|
||||
tagLib.secondaryPrefix & '\l')
|
||||
tagLib.secondaryPrefix & newline)
|
||||
target.write("--- ")
|
||||
except:
|
||||
var e = newException(YamlPresenterOutputError, "")
|
||||
|
@ -352,16 +360,16 @@ proc present*(s: var YamlStream, target: Stream, tagLib: TagLibrary,
|
|||
raise e
|
||||
of yamlScalar:
|
||||
if levels.len == 0:
|
||||
if style != psJson:
|
||||
safeWrite('\l')
|
||||
if options.style != psJson:
|
||||
safeWrite(newline)
|
||||
else:
|
||||
startItem(target, style, indentation, levels[levels.high],
|
||||
false)
|
||||
if style != psJson:
|
||||
startItem(target, options.style, indentation,
|
||||
levels[levels.high], false, newline)
|
||||
if options.style != psJson:
|
||||
writeTagAndAnchor(target,
|
||||
item.scalarTag, tagLib, item.scalarAnchor)
|
||||
|
||||
if style == psJson:
|
||||
if options.style == psJson:
|
||||
let hint = guessType(item.scalarContent)
|
||||
if item.scalarTag in [yTagQuestionMark, yTagBoolean] and
|
||||
hint in [yTypeBoolTrue, yTypeBoolFalse]:
|
||||
|
@ -384,26 +392,28 @@ proc present*(s: var YamlStream, target: Stream, tagLib: TagLibrary,
|
|||
safeWrite(item.scalarContent)
|
||||
else:
|
||||
writeDoubleQuotedJson(item.scalarContent, target)
|
||||
elif style == psCanonical:
|
||||
elif options.style == psCanonical:
|
||||
writeDoubleQuoted(item.scalarContent, target,
|
||||
indentation + indentationStep)
|
||||
indentation + options.indentationStep,
|
||||
newline)
|
||||
else:
|
||||
var words, lines = newSeq[tuple[start, finish: int]]()
|
||||
case item.scalarContent.inspect(indentation + indentationStep,
|
||||
words, lines)
|
||||
case item.scalarContent.inspect(
|
||||
indentation + options.indentationStep, words, lines)
|
||||
of sLiteral: writeLiteral(item.scalarContent, indentation,
|
||||
indentationStep, target, lines)
|
||||
options.indentationStep, target, lines, newline)
|
||||
of sFolded: writeFolded(item.scalarContent, indentation,
|
||||
indentationStep, target, words)
|
||||
options.indentationStep, target, words, newline)
|
||||
of sPlain: safeWrite(item.scalarContent)
|
||||
of sDoubleQuoted: writeDoubleQuoted(item.scalarContent, target,
|
||||
indentation + indentationStep)
|
||||
indentation + options.indentationStep, newline)
|
||||
of yamlAlias:
|
||||
if style == psJson:
|
||||
if options.style == psJson:
|
||||
raise newException(YamlPresenterJsonError,
|
||||
"Alias not allowed in JSON output")
|
||||
assert levels.len > 0
|
||||
startItem(target, style, indentation, levels[levels.high], false)
|
||||
startItem(target, options.style, indentation, levels[levels.high],
|
||||
false, newline)
|
||||
try:
|
||||
target.write('*')
|
||||
target.write(cast[byte]('a') + cast[byte](item.aliasTarget))
|
||||
|
@ -413,7 +423,7 @@ proc present*(s: var YamlStream, target: Stream, tagLib: TagLibrary,
|
|||
raise e
|
||||
of yamlStartSequence:
|
||||
var nextState: DumperState
|
||||
case style
|
||||
case options.style
|
||||
of psDefault:
|
||||
var length = 0
|
||||
while true:
|
||||
|
@ -445,33 +455,34 @@ proc present*(s: var YamlStream, target: Stream, tagLib: TagLibrary,
|
|||
|
||||
if levels.len == 0:
|
||||
if nextState == dBlockSequenceItem:
|
||||
if style != psJson:
|
||||
if options.style != psJson:
|
||||
writeTagAndAnchor(target,
|
||||
item.seqTag, tagLib, item.seqAnchor)
|
||||
else:
|
||||
if style != psJson:
|
||||
if options.style != psJson:
|
||||
writeTagAndAnchor(target,
|
||||
item.seqTag, tagLib, item.seqAnchor)
|
||||
safeWrite('\l')
|
||||
indentation += indentationStep
|
||||
safeWrite(newline)
|
||||
indentation += options.indentationStep
|
||||
else:
|
||||
startItem(target, style, indentation, levels[levels.high], true)
|
||||
if style != psJson:
|
||||
startItem(target, options.style, indentation,
|
||||
levels[levels.high], true, newline)
|
||||
if options.style != psJson:
|
||||
writeTagAndAnchor(target,
|
||||
item.seqTag, tagLib, item.seqAnchor)
|
||||
indentation += indentationStep
|
||||
indentation += options.indentationStep
|
||||
|
||||
if nextState == dFlowSequenceStart:
|
||||
safeWrite('[')
|
||||
if levels.len > 0 and style in [psJson, psCanonical] and
|
||||
if levels.len > 0 and options.style in [psJson, psCanonical] and
|
||||
levels[levels.high] in
|
||||
[dBlockExplicitMapKey, dBlockMapValue,
|
||||
dBlockImplicitMapKey, dBlockSequenceItem]:
|
||||
indentation += indentationStep
|
||||
indentation += options.indentationStep
|
||||
levels.add(nextState)
|
||||
of yamlStartMap:
|
||||
var nextState: DumperState
|
||||
case style
|
||||
case options.style
|
||||
of psDefault:
|
||||
type MapParseState = enum
|
||||
mpInitial, mpKey, mpValue, mpNeedBlock
|
||||
|
@ -503,50 +514,50 @@ proc present*(s: var YamlStream, target: Stream, tagLib: TagLibrary,
|
|||
nextState = dBlockMapValue
|
||||
if levels.len == 0:
|
||||
if nextState == dBlockMapValue:
|
||||
if style != psJson:
|
||||
if options.style != psJson:
|
||||
writeTagAndAnchor(target,
|
||||
item.mapTag, tagLib, item.mapAnchor)
|
||||
else:
|
||||
if style != psJson:
|
||||
safeWrite('\l')
|
||||
if options.style != psJson:
|
||||
safeWrite(newline)
|
||||
writeTagAndAnchor(target,
|
||||
item.mapTag, tagLib, item.mapAnchor)
|
||||
indentation += indentationStep
|
||||
indentation += options.indentationStep
|
||||
else:
|
||||
if nextState in [dBlockMapValue, dBlockImplicitMapKey]:
|
||||
startItem(target, style, indentation, levels[levels.high],
|
||||
true)
|
||||
if style != psJson:
|
||||
startItem(target, options.style, indentation,
|
||||
levels[levels.high], true, newline)
|
||||
if options.style != psJson:
|
||||
writeTagAndAnchor(target,
|
||||
item.mapTag, tagLib, item.mapAnchor)
|
||||
else:
|
||||
startItem(target, style, indentation, levels[levels.high],
|
||||
true)
|
||||
if style != psJson:
|
||||
startItem(target, options.style, indentation,
|
||||
levels[levels.high], true, newline)
|
||||
if options.style != psJson:
|
||||
writeTagAndAnchor(target,
|
||||
item.mapTag, tagLib, item.mapAnchor)
|
||||
indentation += indentationStep
|
||||
indentation += options.indentationStep
|
||||
|
||||
if nextState == dFlowMapStart:
|
||||
safeWrite('{')
|
||||
if levels.len > 0 and style in [psJson, psCanonical] and
|
||||
if levels.len > 0 and options.style in [psJson, psCanonical] and
|
||||
levels[levels.high] in
|
||||
[dBlockExplicitMapKey, dBlockMapValue,
|
||||
dBlockImplicitMapKey, dBlockSequenceItem]:
|
||||
indentation += indentationStep
|
||||
indentation += options.indentationStep
|
||||
levels.add(nextState)
|
||||
|
||||
of yamlEndSequence:
|
||||
assert levels.len > 0
|
||||
case levels.pop()
|
||||
of dFlowSequenceItem:
|
||||
case style
|
||||
case options.style
|
||||
of psDefault, psMinimal, psBlockOnly:
|
||||
safeWrite(']')
|
||||
of psJson, psCanonical:
|
||||
indentation -= indentationStep
|
||||
indentation -= options.indentationStep
|
||||
try:
|
||||
target.write('\l')
|
||||
target.write(newline)
|
||||
target.write(repeat(' ', indentation))
|
||||
target.write(']')
|
||||
except:
|
||||
|
@ -558,29 +569,29 @@ proc present*(s: var YamlStream, target: Stream, tagLib: TagLibrary,
|
|||
dBlockImplicitMapKey, dBlockSequenceItem]:
|
||||
continue
|
||||
of dFlowSequenceStart:
|
||||
if levels.len > 0 and style in [psJson, psCanonical] and
|
||||
if levels.len > 0 and options.style in [psJson, psCanonical] and
|
||||
levels[levels.high] in
|
||||
[dBlockExplicitMapKey, dBlockMapValue,
|
||||
dBlockImplicitMapKey, dBlockSequenceItem]:
|
||||
indentation -= indentationStep
|
||||
indentation -= options.indentationStep
|
||||
safeWrite(']')
|
||||
of dBlockSequenceItem:
|
||||
discard
|
||||
else:
|
||||
assert false
|
||||
indentation -= indentationStep
|
||||
indentation -= options.indentationStep
|
||||
of yamlEndMap:
|
||||
assert levels.len > 0
|
||||
let level = levels.pop()
|
||||
case level
|
||||
of dFlowMapValue:
|
||||
case style
|
||||
case options.style
|
||||
of psDefault, psMinimal, psBlockOnly:
|
||||
safeWrite('}')
|
||||
of psJson, psCanonical:
|
||||
indentation -= indentationStep
|
||||
indentation -= options.indentationStep
|
||||
try:
|
||||
target.write('\l')
|
||||
target.write(newline)
|
||||
target.write(repeat(' ', indentation))
|
||||
target.write('}')
|
||||
except:
|
||||
|
@ -592,29 +603,29 @@ proc present*(s: var YamlStream, target: Stream, tagLib: TagLibrary,
|
|||
dBlockImplicitMapKey, dBlockSequenceItem]:
|
||||
continue
|
||||
of dFlowMapStart:
|
||||
if levels.len > 0 and style in [psJson, psCanonical] and
|
||||
if levels.len > 0 and options.style in [psJson, psCanonical] and
|
||||
levels[levels.high] in
|
||||
[dBlockExplicitMapKey, dBlockMapValue,
|
||||
dBlockImplicitMapKey, dBlockSequenceItem]:
|
||||
indentation -= indentationStep
|
||||
indentation -= options.indentationStep
|
||||
safeWrite('}')
|
||||
of dBlockMapValue, dBlockInlineMap:
|
||||
discard
|
||||
else:
|
||||
assert false
|
||||
indentation -= indentationStep
|
||||
indentation -= options.indentationStep
|
||||
of yamlEndDocument:
|
||||
if finished(s): break
|
||||
safeWrite("...\l")
|
||||
safeWrite("..." & newline)
|
||||
|
||||
proc transform*(input: Stream, output: Stream, style: PresentationStyle,
|
||||
indentationStep: int = 2) =
|
||||
proc transform*(input: Stream, output: Stream,
|
||||
options: PresentationOptions = defaultPresentationOptions) =
|
||||
var
|
||||
taglib = initExtendedTagLibrary()
|
||||
parser = newYamlParser(tagLib)
|
||||
events = parser.parse(input)
|
||||
try:
|
||||
if style == psCanonical:
|
||||
if options.style == psCanonical:
|
||||
var specificTagEvents = iterator(): YamlStreamEvent =
|
||||
for e in events:
|
||||
var event = e
|
||||
|
@ -647,10 +658,9 @@ proc transform*(input: Stream, output: Stream, style: PresentationStyle,
|
|||
event.scalarTag = yTagString
|
||||
yield event
|
||||
var s = initYamlStream(specificTagEvents)
|
||||
present(s, output, tagLib, style,
|
||||
indentationStep)
|
||||
present(s, output, tagLib, options)
|
||||
else:
|
||||
present(events, output, tagLib, style, indentationStep)
|
||||
present(events, output, tagLib, options)
|
||||
except YamlStreamError:
|
||||
var e = getCurrentException()
|
||||
while e.parent of YamlStreamError: e = e.parent
|
||||
|
|
|
@ -635,13 +635,14 @@ proc represent*[T](value: T, ts: TagStyle = tsRootOnly,
|
|||
else:
|
||||
result = initYamlStream(objStream)
|
||||
|
||||
proc dump*[K](value: K, target: Stream, style: PresentationStyle = psDefault,
|
||||
tagStyle: TagStyle = tsRootOnly,
|
||||
anchorStyle: AnchorStyle = asTidy, indentationStep: int = 2) =
|
||||
var events = represent(value, if style == psCanonical: tsAll else: tagStyle,
|
||||
if style == psJson: asNone else: anchorStyle)
|
||||
proc dump*[K](value: K, target: Stream, tagStyle: TagStyle = tsRootOnly,
|
||||
anchorStyle: AnchorStyle = asTidy,
|
||||
options: PresentationOptions = defaultPresentationOptions) =
|
||||
var events = represent(value,
|
||||
if options.style == psCanonical: tsAll else: tagStyle,
|
||||
if options.style == psJson: asNone else: anchorStyle)
|
||||
try:
|
||||
present(events, target, serializationTagLibrary, style, indentationStep)
|
||||
present(events, target, serializationTagLibrary, options)
|
||||
except YamlStreamError:
|
||||
# serializing object does not raise any errors, so we can ignore this
|
||||
assert false, "Can never happen"
|
|
@ -55,6 +55,11 @@ proc newNode(v: string): ref Node =
|
|||
result.next = nil
|
||||
|
||||
suite "Serialization":
|
||||
setup:
|
||||
let
|
||||
blockOnly = defineOptions(style=psBlockOnly)
|
||||
|
||||
|
||||
test "Serialization: Load string sequence":
|
||||
let input = newStringStream(" - a\n - b")
|
||||
var result: seq[string]
|
||||
|
@ -66,7 +71,7 @@ suite "Serialization":
|
|||
test "Serialization: Represent string sequence":
|
||||
var input = @["a", "b"]
|
||||
var output = newStringStream()
|
||||
dump(input, output, psBlockOnly, tsNone)
|
||||
dump(input, output, tsNone, asTidy, blockOnly)
|
||||
assertStringEqual "%YAML 1.2\n--- \n- a\n- b", output.data
|
||||
|
||||
test "Serialization: Load Table[int, string]":
|
||||
|
@ -82,7 +87,7 @@ suite "Serialization":
|
|||
input[23] = "dreiundzwanzig"
|
||||
input[42] = "zweiundvierzig"
|
||||
var output = newStringStream()
|
||||
dump(input, output, psBlockOnly, tsNone)
|
||||
dump(input, output, tsNone, asTidy, blockOnly)
|
||||
assertStringEqual(
|
||||
"%YAML 1.2\n--- \n23: dreiundzwanzig\n42: zweiundvierzig",
|
||||
output.data)
|
||||
|
@ -100,7 +105,7 @@ suite "Serialization":
|
|||
let input = @[@[1.int32, 2.int32, 3.int32], @[4.int32, 5.int32],
|
||||
@[6.int32]]
|
||||
var output = newStringStream()
|
||||
dump(input, output, psDefault, tsNone)
|
||||
dump(input, output, tsNone)
|
||||
assertStringEqual "%YAML 1.2\n--- \n- [1, 2, 3]\n- [4, 5]\n- [6]",
|
||||
output.data
|
||||
|
||||
|
@ -116,7 +121,7 @@ suite "Serialization":
|
|||
test "Serialization: Represent Enum":
|
||||
let input = @[tlRed, tlGreen, tlYellow]
|
||||
var output = newStringStream()
|
||||
dump(input, output, psBlockOnly, tsNone)
|
||||
dump(input, output, tsNone, asTidy, blockOnly)
|
||||
assertStringEqual "%YAML 1.2\n--- \n- tlRed\n- tlGreen\n- tlYellow",
|
||||
output.data
|
||||
|
||||
|
@ -131,7 +136,7 @@ suite "Serialization":
|
|||
test "Serialization: Represent Tuple":
|
||||
let input = (str: "value", i: 42.int32, b: true)
|
||||
var output = newStringStream()
|
||||
dump(input, output, psDefault, tsNone)
|
||||
dump(input, output, tsNone)
|
||||
assertStringEqual "%YAML 1.2\n--- \nstr: value\ni: 42\nb: y",
|
||||
output.data
|
||||
|
||||
|
@ -146,7 +151,7 @@ suite "Serialization":
|
|||
test "Serialization: Represent custom object":
|
||||
let input = Person(firstnamechar: 'P', surname: "Pan", age: 12)
|
||||
var output = newStringStream()
|
||||
dump(input, output, psBlockOnly, tsNone)
|
||||
dump(input, output, tsNone, asTidy, blockOnly)
|
||||
assertStringEqual(
|
||||
"%YAML 1.2\n--- \nfirstnamechar: P\nsurname: Pan\nage: 12",
|
||||
output.data)
|
||||
|
@ -162,7 +167,7 @@ suite "Serialization":
|
|||
test "Serialization: Represent sequence with explicit tags":
|
||||
let input = @["one", "two"]
|
||||
var output = newStringStream()
|
||||
dump(input, output, psBlockOnly, tsAll)
|
||||
dump(input, output, tsAll, asTidy, blockOnly)
|
||||
assertStringEqual("%YAML 1.2\n--- !nim:system:seq(" &
|
||||
"tag:yaml.org,2002:str) \n- !!str one\n- !!str two",
|
||||
output.data)
|
||||
|
@ -179,7 +184,7 @@ suite "Serialization":
|
|||
test "Serialization: Represent custom object with explicit root tag":
|
||||
let input = Person(firstnamechar: 'P', surname: "Pan", age: 12)
|
||||
var output = newStringStream()
|
||||
dump(input, output, psBlockOnly, tsRootOnly)
|
||||
dump(input, output, tsRootOnly, asTidy, blockOnly)
|
||||
assertStringEqual("%YAML 1.2\n" &
|
||||
"--- !nim:custom:Person \nfirstnamechar: P\nsurname: Pan\nage: 12",
|
||||
output.data)
|
||||
|
@ -193,7 +198,7 @@ suite "Serialization":
|
|||
b.next = c
|
||||
c.next = a
|
||||
var output = newStringStream()
|
||||
dump(a, output, psBlockOnly, tsRootOnly)
|
||||
dump(a, output, tsRootOnly, asTidy, blockOnly)
|
||||
assertStringEqual """%YAML 1.2
|
||||
--- !example.net:Node &a
|
||||
value: a
|
||||
|
@ -252,7 +257,7 @@ next:
|
|||
input.add(new string)
|
||||
input[1][] = "~"
|
||||
var output = newStringStream()
|
||||
dump(input, output, psBlockOnly, tsRootOnly)
|
||||
dump(input, output, tsRootOnly, asTidy, blockOnly)
|
||||
assertStringEqual "%YAML 1.2\n--- !nim:system:seq(tag:yaml.org,2002:str) \n- !!null ~\n- !!str ~",
|
||||
output.data
|
||||
|
||||
|
@ -267,7 +272,7 @@ next:
|
|||
test "Serialization: Custom representObject":
|
||||
let input = @[1.BetterInt, 9998887.BetterInt, 98312.BetterInt]
|
||||
var output = newStringStream()
|
||||
dump(input, output, psBlockOnly, tsAll)
|
||||
dump(input, output, tsAll, asTidy, blockOnly)
|
||||
assertStringEqual """%YAML 1.2
|
||||
--- !nim:system:seq(test:BetterInt)
|
||||
- !test:BetterInt 1
|
||||
|
|
48
yaml.nim
48
yaml.nim
|
@ -205,6 +205,22 @@ type
|
|||
## object is referenced again afterwards
|
||||
asNone, asTidy, asAlways
|
||||
|
||||
NewLineStyle* = enum
|
||||
## What kind of newline sequence is used when presenting.
|
||||
##
|
||||
## - ``nlLF``: Use a single linefeed char as newline.
|
||||
## - ``nlCRLF``: Use a sequence of carriage return and linefeed as
|
||||
## newline.
|
||||
## - ``nlOSDefault``: Use the target operation system's default newline
|
||||
## sequence (CRLF on Windows, LF everywhere else).
|
||||
nlLF, nlCRLF, nlOSDefault
|
||||
|
||||
PresentationOptions* = object
|
||||
## Options for generating a YAML character stream
|
||||
style*: PresentationStyle
|
||||
indentationStep*: int
|
||||
newlines*: NewLineStyle
|
||||
|
||||
RefNodeData = object
|
||||
p: pointer
|
||||
count: int
|
||||
|
@ -361,6 +377,10 @@ const
|
|||
|
||||
yamlTagRepositoryPrefix* = "tag:yaml.org,2002:"
|
||||
|
||||
defaultPresentationOptions* =
|
||||
PresentationOptions(style: psDefault, indentationStep: 2,
|
||||
newlines: nlOSDefault)
|
||||
|
||||
# interface
|
||||
|
||||
proc `==`*(left: YamlStreamEvent, right: YamlStreamEvent): bool {.raises: [].}
|
||||
|
@ -495,6 +515,13 @@ proc getLineContent*(p: YamlParser, marker: bool = true): string {.raises: [].}
|
|||
proc parse*(p: YamlParser, s: Stream): YamlStream {.raises: [].}
|
||||
## Parse the given stream as YAML character stream.
|
||||
|
||||
proc defineOptions*(style: PresentationStyle = psDefault,
|
||||
indentationStep: int = 2, newlines:
|
||||
NewLineStyle = nlOSDefault): PresentationOptions
|
||||
{.raises: [].}
|
||||
## Define a set of options for presentation. Convenience proc that requires
|
||||
## you to only set those values that should not equal the default.
|
||||
|
||||
proc constructJson*(s: var YamlStream): seq[JsonNode]
|
||||
{.raises: [YamlConstructionError, YamlStreamError].}
|
||||
## Construct an in-memory JSON tree from a YAML event stream. The stream may
|
||||
|
@ -516,16 +543,15 @@ proc loadToJson*(s: Stream): seq[JsonNode] {.raises: [].}
|
|||
## from a YAML character stream.
|
||||
|
||||
proc present*(s: var YamlStream, target: Stream, tagLib: TagLibrary,
|
||||
style: PresentationStyle = psDefault,
|
||||
indentationStep: int = 2) {.raises: [YamlPresenterJsonError,
|
||||
YamlPresenterOutputError,
|
||||
YamlStreamError].}
|
||||
options: PresentationOptions = defaultPresentationOptions)
|
||||
{.raises: [YamlPresenterJsonError, YamlPresenterOutputError,
|
||||
YamlStreamError].}
|
||||
## Convert ``s`` to a YAML character stream and write it to ``target``.
|
||||
|
||||
proc transform*(input: Stream, output: Stream, style: PresentationStyle,
|
||||
indentationStep: int = 2) {.raises: [IOError, YamlParserError,
|
||||
YamlPresenterJsonError,
|
||||
YamlPresenterOutputError].}
|
||||
proc transform*(input: Stream, output: Stream,
|
||||
options: PresentationOptions = defaultPresentationOptions)
|
||||
{.raises: [IOError, YamlParserError, YamlPresenterJsonError,
|
||||
YamlPresenterOutputError].}
|
||||
## Parser ``input`` as YAML character stream and then dump it to ``output``
|
||||
## while resolving non-specific tags to the ones in the YAML core tag
|
||||
## library.
|
||||
|
@ -564,9 +590,9 @@ proc represent*[T](value: T, ts: TagStyle = tsRootOnly,
|
|||
a: AnchorStyle = asTidy): YamlStream {.raises: [].}
|
||||
## Represents a Nim value as ``YamlStream``
|
||||
|
||||
proc dump*[K](value: K, target: Stream, style: PresentationStyle = psDefault,
|
||||
tagStyle: TagStyle = tsRootOnly,
|
||||
anchorStyle: AnchorStyle = asTidy, indentationStep: int = 2)
|
||||
proc dump*[K](value: K, target: Stream, tagStyle: TagStyle = tsRootOnly,
|
||||
anchorStyle: AnchorStyle = asTidy,
|
||||
options: PresentationOptions = defaultPresentationOptions)
|
||||
{.raises: [YamlPresenterJsonError, YamlPresenterOutputError].}
|
||||
## Dump a Nim value as YAML character stream.
|
||||
|
||||
|
|
Loading…
Reference in New Issue