mirror of https://github.com/status-im/NimYAML.git
Fixed presenter regarding new style annotations
* fixed presentation of flow mappings inside block collections * improved logic checking whether a collection can be written on a single line * fixed tests
This commit is contained in:
parent
a698289223
commit
bf87d508d0
|
@ -676,14 +676,16 @@ suite "Serialization":
|
||||||
flowChild: AsFlow(a: "abc", b: "abc", c: "abc"),
|
flowChild: AsFlow(a: "abc", b: "abc", c: "abc"),
|
||||||
blockChild: AsFlow(a: "a\nc", b: "abc", c: "ab:")
|
blockChild: AsFlow(a: "a\nc", b: "abc", c: "ab:")
|
||||||
)
|
)
|
||||||
var output = blockOnlyDumper().dump(input)
|
var dumper = blockOnlyDumper()
|
||||||
|
dumper.presentation.maxLineLength = some(20)
|
||||||
|
var output = dumper.dump(input)
|
||||||
assertStringEqual "flowChild: {\n" &
|
assertStringEqual "flowChild: {\n" &
|
||||||
" a: 'abc',\n" &
|
" a: 'abc',\n" &
|
||||||
" b: \"abc\",\n" &
|
" b: \"abc\",\n" &
|
||||||
" c: abc\n" &
|
" c: abc\n" &
|
||||||
" }\n" &
|
" }\n" &
|
||||||
"blockChild:\n" &
|
"blockChild:\n" &
|
||||||
" a: \"a\\\nc\"\n" &
|
" a: \"a\\nc\"\n" &
|
||||||
" b: \"abc\"\n" &
|
" b: \"abc\"\n" &
|
||||||
" c: \"ab:\"\n", output
|
" c: \"ab:\"\n", output
|
||||||
|
|
|
@ -53,7 +53,7 @@ suite "Presenter":
|
||||||
|
|
||||||
test "Forced multiline flow sequence":
|
test "Forced multiline flow sequence":
|
||||||
var input = inputSingle(startSeqEvent(), scalarEvent("1"), scalarEvent("2"), endSeqEvent())
|
var input = inputSingle(startSeqEvent(), scalarEvent("1"), scalarEvent("2"), endSeqEvent())
|
||||||
assertOutput(input, "[\n 1,\n 2\n]\n", PresentationOptions(outputVersion: ovNone, condenseFlow: false))
|
assertOutput(input, "[\n 1,\n 2\n]\n", PresentationOptions(outputVersion: ovNone, condenseFlow: false, containers: cFlow))
|
||||||
|
|
||||||
test "Compact flow mapping":
|
test "Compact flow mapping":
|
||||||
var input = inputSingle(startMapEvent(), scalarEvent("1"), scalarEvent("2"), endMapEvent())
|
var input = inputSingle(startMapEvent(), scalarEvent("1"), scalarEvent("2"), endMapEvent())
|
||||||
|
|
|
@ -33,7 +33,8 @@ proc setMinimalStyle*(dumper: var Dumper) =
|
||||||
suppressAttrs: false,
|
suppressAttrs: false,
|
||||||
quoting: sqJson,
|
quoting: sqJson,
|
||||||
condenseFlow: true,
|
condenseFlow: true,
|
||||||
explicitKeys: false
|
explicitKeys: false,
|
||||||
|
maxLineLength: none(int)
|
||||||
)
|
)
|
||||||
dumper.serialization = SerializationOptions(
|
dumper.serialization = SerializationOptions(
|
||||||
tagStyle: tsNone,
|
tagStyle: tsNone,
|
||||||
|
|
|
@ -1243,7 +1243,6 @@ proc recGenFieldRepresenters(
|
||||||
))
|
))
|
||||||
when `fieldAccessor`.hasCustomPragma(scalar):
|
when `fieldAccessor`.hasCustomPragma(scalar):
|
||||||
ctx.overridingScalarStyle = `fieldAccessor`.getCustomPragmaVal(scalar)
|
ctx.overridingScalarStyle = `fieldAccessor`.getCustomPragmaVal(scalar)
|
||||||
echo "set scalar style to ", $ctx.overridingScalarStyle
|
|
||||||
when `fieldAccessor`.hasCustomPragma(collection):
|
when `fieldAccessor`.hasCustomPragma(collection):
|
||||||
ctx.overridingCollectionStyle = `fieldAccessor`.getCustomPragmaVal(collection)
|
ctx.overridingCollectionStyle = `fieldAccessor`.getCustomPragmaVal(collection)
|
||||||
ctx.representChild(`fieldAccessor`)
|
ctx.representChild(`fieldAccessor`)
|
||||||
|
@ -1281,7 +1280,6 @@ proc recGenFieldRepresenters(
|
||||||
))
|
))
|
||||||
when `itemAccessor`.hasCustomPragma(scalar):
|
when `itemAccessor`.hasCustomPragma(scalar):
|
||||||
ctx.overridingScalarStyle = `itemAccessor`.getCustomPragmaVal(scalar)
|
ctx.overridingScalarStyle = `itemAccessor`.getCustomPragmaVal(scalar)
|
||||||
echo "set scalar style to ", $ctx.overridingScalarStyle
|
|
||||||
when `itemAccessor`.hasCustomPragma(collection):
|
when `itemAccessor`.hasCustomPragma(collection):
|
||||||
ctx.overridingCollectionStyle = `itemAccessor`.getCustomPragmaVal(collection)
|
ctx.overridingCollectionStyle = `itemAccessor`.getCustomPragmaVal(collection)
|
||||||
ctx.representChild(`itemAccessor`)
|
ctx.representChild(`itemAccessor`)
|
||||||
|
@ -1307,7 +1305,6 @@ proc recGenFieldRepresenters(
|
||||||
))
|
))
|
||||||
when `childAccessor`.hasCustomPragma(scalar):
|
when `childAccessor`.hasCustomPragma(scalar):
|
||||||
ctx.overridingScalarStyle = `childAccessor`.getCustomPragmaVal(scalar)
|
ctx.overridingScalarStyle = `childAccessor`.getCustomPragmaVal(scalar)
|
||||||
echo "set scalar style to ", $ctx.overridingScalarStyle
|
|
||||||
when `childAccessor`.hasCustomPragma(collection):
|
when `childAccessor`.hasCustomPragma(collection):
|
||||||
ctx.overridingCollectionStyle = `childAccessor`.getCustomPragmaVal(collection)
|
ctx.overridingCollectionStyle = `childAccessor`.getCustomPragmaVal(collection)
|
||||||
ctx.representChild(`childAccessor`)
|
ctx.representChild(`childAccessor`)
|
||||||
|
|
|
@ -111,9 +111,13 @@ type
|
||||||
needsWhitespace: int
|
needsWhitespace: int
|
||||||
wroteDirectivesEnd: bool
|
wroteDirectivesEnd: bool
|
||||||
lastImplicitKeyLen: int
|
lastImplicitKeyLen: int
|
||||||
|
cached: DeQue[Event]
|
||||||
|
|
||||||
ItemKind = enum
|
ItemKind = enum
|
||||||
ikCompactScalar, ikMultilineFlowScalar, ikBlockScalar, ikCollection
|
ikCompactScalar, ikMultilineFlowScalar, ikBlockScalar, ikCollection
|
||||||
|
|
||||||
|
MapParseState = enum
|
||||||
|
mpInitial, mpKey, mpValue, mpNeedBlock
|
||||||
|
|
||||||
proc level(ctx: var Context): var DumperLevel = ctx.levels[^1]
|
proc level(ctx: var Context): var DumperLevel = ctx.levels[^1]
|
||||||
|
|
||||||
|
@ -595,7 +599,7 @@ proc startItem(
|
||||||
of dFlowSequenceItem:
|
of dFlowSequenceItem:
|
||||||
ctx.append(',')
|
ctx.append(',')
|
||||||
ctx.whitespace(true)
|
ctx.whitespace(true)
|
||||||
if not ctx.options.condenseFlow:
|
if not ctx.level.singleLine:
|
||||||
ctx.newline()
|
ctx.newline()
|
||||||
t.write(repeat(' ', ctx.indentation))
|
t.write(repeat(' ', ctx.indentation))
|
||||||
except CatchableError as ce:
|
except CatchableError as ce:
|
||||||
|
@ -644,6 +648,49 @@ proc nextItem(
|
||||||
else:
|
else:
|
||||||
result = s.next()
|
result = s.next()
|
||||||
|
|
||||||
|
proc checkSingleLine(
|
||||||
|
ctx : var Context,
|
||||||
|
s : YamlStream,
|
||||||
|
item : Event,
|
||||||
|
mapping: bool
|
||||||
|
): (bool, MapParseState) =
|
||||||
|
let style = if mapping: item.mapStyle else: item.seqStyle
|
||||||
|
if ctx.options.newlines == nlNone: return (true, mpInitial)
|
||||||
|
if not ctx.options.condenseFlow: return (false, mpNeedBlock)
|
||||||
|
if (ctx.levels.len > 0 and ctx.state.isFlow) or style == csFlow or
|
||||||
|
(style == csAny and ctx.options.containers != cBlock):
|
||||||
|
result[1] = mpInitial
|
||||||
|
var length = 0
|
||||||
|
while not mapping or result[1] != mpNeedBlock:
|
||||||
|
let next = s.next()
|
||||||
|
ctx.cached.addLast(next)
|
||||||
|
case next.kind
|
||||||
|
of yamlScalar:
|
||||||
|
length += 2 + next.scalarContent.len
|
||||||
|
if next.scalarStyle in [ssFolded, ssLiteral]:
|
||||||
|
length = high(int)
|
||||||
|
result[1] = mpNeedBlock
|
||||||
|
break
|
||||||
|
case result[1]
|
||||||
|
of mpInitial: result[1] = mpKey
|
||||||
|
of mpKey: result[1] = mpValue
|
||||||
|
else: result[1] = mpNeedBlock
|
||||||
|
of yamlAlias:
|
||||||
|
length += 6
|
||||||
|
case result[1]
|
||||||
|
of mpInitial: result[1] = mpKey
|
||||||
|
of mpKey: result[1] = mpValue
|
||||||
|
else: result[1] = mpNeedBlock
|
||||||
|
of yamlEndSeq, yamlEndMap: break
|
||||||
|
else:
|
||||||
|
length = high(int)
|
||||||
|
result[1] = mpNeedBlock
|
||||||
|
break
|
||||||
|
result[0] = (not mapping or result[1] != mpNeedBlock) and
|
||||||
|
(ctx.options.maxLineLength.isNone or
|
||||||
|
length < ctx.options.maxLineLength.get() - ctx.indentation - 2)
|
||||||
|
else: result = (false, mpNeedBlock)
|
||||||
|
|
||||||
proc doPresent(
|
proc doPresent(
|
||||||
ctx: var Context,
|
ctx: var Context,
|
||||||
s : YamlStream,
|
s : YamlStream,
|
||||||
|
@ -651,12 +698,11 @@ proc doPresent(
|
||||||
YamlPresenterJsonError, YamlPresenterOutputError,
|
YamlPresenterJsonError, YamlPresenterOutputError,
|
||||||
YamlStreamError
|
YamlStreamError
|
||||||
].} =
|
].} =
|
||||||
var
|
var unclosedDoc = false
|
||||||
cached = initDeQue[Event]()
|
ctx.cached = initDeQue[Event]()
|
||||||
unclosedDoc = false
|
|
||||||
ctx.wroteDirectivesEnd = false
|
ctx.wroteDirectivesEnd = false
|
||||||
while true:
|
while true:
|
||||||
let item = nextItem(cached, s)
|
let item = nextItem(ctx.cached, s)
|
||||||
case item.kind
|
case item.kind
|
||||||
of yamlStartStream: discard
|
of yamlStartStream: discard
|
||||||
of yamlEndStream: break
|
of yamlEndStream: break
|
||||||
|
@ -801,6 +847,7 @@ proc doPresent(
|
||||||
e.parent = ce
|
e.parent = ce
|
||||||
raise e
|
raise e
|
||||||
of yamlStartSeq:
|
of yamlStartSeq:
|
||||||
|
let (singleLine, _) = ctx.checkSingleLine(s, item, false)
|
||||||
var nextState: DumperState
|
var nextState: DumperState
|
||||||
if (ctx.levels.len > 0 and ctx.state.isFlow) or item.seqStyle == csFlow:
|
if (ctx.levels.len > 0 and ctx.state.isFlow) or item.seqStyle == csFlow:
|
||||||
nextState = dFlowSequenceStart
|
nextState = dFlowSequenceStart
|
||||||
|
@ -810,31 +857,13 @@ proc doPresent(
|
||||||
else:
|
else:
|
||||||
case ctx.options.containers
|
case ctx.options.containers
|
||||||
of cMixed:
|
of cMixed:
|
||||||
var length = 0
|
nextState = if singleLine: dFlowSequenceStart else: dBlockSequenceItem
|
||||||
while true:
|
|
||||||
let next = s.next()
|
|
||||||
cached.addLast(next)
|
|
||||||
case next.kind
|
|
||||||
of yamlScalar:
|
|
||||||
length += 2 + next.scalarContent.len
|
|
||||||
if next.scalarStyle in [ssFolded, ssLiteral]:
|
|
||||||
length = high(int)
|
|
||||||
break
|
|
||||||
of yamlAlias: length += 6
|
|
||||||
of yamlEndSeq: break
|
|
||||||
else:
|
|
||||||
length = high(int)
|
|
||||||
break
|
|
||||||
nextState = if length <= 60: dFlowSequenceStart else: dBlockSequenceItem
|
|
||||||
of cFlow: nextState = dFlowSequenceStart
|
of cFlow: nextState = dFlowSequenceStart
|
||||||
of cBlock:
|
of cBlock:
|
||||||
let next = s.peek()
|
let next = s.peek()
|
||||||
if next.kind == yamlEndSeq: nextState = dFlowSequenceStart
|
nextState = if next.kind == yamlEndSeq: dFlowSequenceStart else: dBlockSequenceItem
|
||||||
else: nextState = dBlockSequenceItem
|
|
||||||
|
|
||||||
var indentation = 0
|
var indentation = 0
|
||||||
var singleLine = ctx.options.condenseFlow or ctx.options.newlines == nlNone
|
|
||||||
|
|
||||||
var wroteAnything = false
|
var wroteAnything = false
|
||||||
if ctx.levels.len > 0: wroteAnything = ctx.state == dBlockImplicitMapKey
|
if ctx.levels.len > 0: wroteAnything = ctx.state == dBlockImplicitMapKey
|
||||||
|
|
||||||
|
@ -844,6 +873,8 @@ proc doPresent(
|
||||||
else:
|
else:
|
||||||
ctx.startItem(ikCollection)
|
ctx.startItem(ikCollection)
|
||||||
indentation = ctx.indentation + ctx.options.indentationStep
|
indentation = ctx.indentation + ctx.options.indentationStep
|
||||||
|
if nextState.isFlow and not ctx.state.isFlow:
|
||||||
|
inc(indentation, ctx.options.indentationStep)
|
||||||
|
|
||||||
let wroteAttrs = ctx.writeTagAndAnchor(item.seqProperties)
|
let wroteAttrs = ctx.writeTagAndAnchor(item.seqProperties)
|
||||||
if wroteAttrs or (ctx.wroteDirectivesEnd and ctx.levels.len == 0):
|
if wroteAttrs or (ctx.wroteDirectivesEnd and ctx.levels.len == 0):
|
||||||
|
@ -854,12 +885,9 @@ proc doPresent(
|
||||||
if wroteAttrs or ctx.wroteDirectivesEnd: ctx.safeNewline()
|
if wroteAttrs or ctx.wroteDirectivesEnd: ctx.safeNewline()
|
||||||
ctx.safeWrite('[')
|
ctx.safeWrite('[')
|
||||||
|
|
||||||
if ctx.levels.len > 0 and not ctx.options.condenseFlow and
|
|
||||||
ctx.state in [dBlockExplicitMapKey, dBlockMapValue,
|
|
||||||
dBlockImplicitMapKey, dBlockSequenceItem]:
|
|
||||||
if ctx.options.newlines != nlNone: singleLine = false
|
|
||||||
ctx.levels.add (nextState, indentation, singleLine, wroteAnything)
|
ctx.levels.add (nextState, indentation, singleLine, wroteAnything)
|
||||||
of yamlStartMap:
|
of yamlStartMap:
|
||||||
|
let (singleLine, mps) = ctx.checkSingleLine(s, item, true)
|
||||||
var nextState: DumperState
|
var nextState: DumperState
|
||||||
if (ctx.levels.len > 0 and ctx.state.isFlow) or item.mapStyle == csFlow:
|
if (ctx.levels.len > 0 and ctx.state.isFlow) or item.mapStyle == csFlow:
|
||||||
nextState = dFlowMapStart
|
nextState = dFlowMapStart
|
||||||
|
@ -869,27 +897,6 @@ proc doPresent(
|
||||||
else:
|
else:
|
||||||
case ctx.options.containers
|
case ctx.options.containers
|
||||||
of cMixed:
|
of cMixed:
|
||||||
type MapParseState = enum
|
|
||||||
mpInitial, mpKey, mpValue, mpNeedBlock
|
|
||||||
var mps: MapParseState = mpInitial
|
|
||||||
while mps != mpNeedBlock:
|
|
||||||
let next = s.next()
|
|
||||||
cached.addLast(next)
|
|
||||||
case next.kind
|
|
||||||
of yamlScalar:
|
|
||||||
case mps
|
|
||||||
of mpInitial: mps = mpKey
|
|
||||||
of mpKey: mps = mpValue
|
|
||||||
else: mps = mpNeedBlock
|
|
||||||
if next.scalarStyle in [ssFolded, ssLiteral]:
|
|
||||||
mps = mpNeedBlock
|
|
||||||
of yamlAlias:
|
|
||||||
case mps
|
|
||||||
of mpInitial: mps = mpKey
|
|
||||||
of mpKey: mps = mpValue
|
|
||||||
else: mps = mpNeedBlock
|
|
||||||
of yamlEndMap: break
|
|
||||||
else: mps = mpNeedBlock
|
|
||||||
if mps == mpNeedBlock:
|
if mps == mpNeedBlock:
|
||||||
nextState = dBlockMapValue
|
nextState = dBlockMapValue
|
||||||
elif ctx.levels.len == 0 or ctx.state == dBlockSequenceItem and item.emptyProperties:
|
elif ctx.levels.len == 0 or ctx.state == dBlockSequenceItem and item.emptyProperties:
|
||||||
|
@ -903,8 +910,6 @@ proc doPresent(
|
||||||
else: nextState = dBlockMapValue
|
else: nextState = dBlockMapValue
|
||||||
|
|
||||||
var indentation = 0
|
var indentation = 0
|
||||||
var singleLine = ctx.options.condenseFlow or ctx.options.newlines == nlNone
|
|
||||||
|
|
||||||
var wroteAnything = false
|
var wroteAnything = false
|
||||||
if ctx.levels.len > 0: wroteAnything = ctx.state == dBlockImplicitMapKey
|
if ctx.levels.len > 0: wroteAnything = ctx.state == dBlockImplicitMapKey
|
||||||
|
|
||||||
|
@ -914,6 +919,8 @@ proc doPresent(
|
||||||
else:
|
else:
|
||||||
ctx.startItem(ikCollection)
|
ctx.startItem(ikCollection)
|
||||||
indentation = ctx.indentation + ctx.options.indentationStep
|
indentation = ctx.indentation + ctx.options.indentationStep
|
||||||
|
if nextState.isFlow and not ctx.state.isFlow:
|
||||||
|
inc(indentation, ctx.options.indentationStep)
|
||||||
|
|
||||||
let wroteAttrs = ctx.writeTagAndAnchor(item.properties)
|
let wroteAttrs = ctx.writeTagAndAnchor(item.properties)
|
||||||
if wroteAttrs or (ctx.wroteDirectivesEnd and ctx.levels.len == 0):
|
if wroteAttrs or (ctx.wroteDirectivesEnd and ctx.levels.len == 0):
|
||||||
|
@ -924,10 +931,6 @@ proc doPresent(
|
||||||
if wroteAttrs or ctx.wroteDirectivesEnd: ctx.safeNewline()
|
if wroteAttrs or ctx.wroteDirectivesEnd: ctx.safeNewline()
|
||||||
ctx.safeWrite('{')
|
ctx.safeWrite('{')
|
||||||
|
|
||||||
if ctx.levels.len > 0 and not ctx.options.condenseFlow and
|
|
||||||
ctx.state in [dBlockExplicitMapKey, dBlockMapValue,
|
|
||||||
dBlockImplicitMapKey, dBlockSequenceItem]:
|
|
||||||
if ctx.options.newlines != nlNone: singleLine = false
|
|
||||||
ctx.levels.add (nextState, indentation, singleLine, wroteAnything)
|
ctx.levels.add (nextState, indentation, singleLine, wroteAnything)
|
||||||
of yamlEndSeq:
|
of yamlEndSeq:
|
||||||
yAssert ctx.levels.len > 0
|
yAssert ctx.levels.len > 0
|
||||||
|
@ -937,7 +940,7 @@ proc doPresent(
|
||||||
try:
|
try:
|
||||||
if not level.singleLine:
|
if not level.singleLine:
|
||||||
ctx.newline()
|
ctx.newline()
|
||||||
ctx.target.write(repeat(' ', ctx.indentation))
|
ctx.target.write(repeat(' ', level.indentation - ctx.options.indentationStep))
|
||||||
ctx.target.write(']')
|
ctx.target.write(']')
|
||||||
except CatchableError as ce:
|
except CatchableError as ce:
|
||||||
var e = newException(YamlPresenterOutputError, "")
|
var e = newException(YamlPresenterOutputError, "")
|
||||||
|
@ -954,7 +957,7 @@ proc doPresent(
|
||||||
try:
|
try:
|
||||||
if not level.singleLine:
|
if not level.singleLine:
|
||||||
ctx.safeNewline()
|
ctx.safeNewline()
|
||||||
ctx.target.write(repeat(' ', ctx.indentation))
|
ctx.target.write(repeat(' ', level.indentation - ctx.options.indentationStep))
|
||||||
ctx.append('}')
|
ctx.append('}')
|
||||||
except CatchableError as ce:
|
except CatchableError as ce:
|
||||||
var e = newException(YamlPresenterOutputError, "")
|
var e = newException(YamlPresenterOutputError, "")
|
||||||
|
|
Loading…
Reference in New Issue