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"),
|
||||
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" &
|
||||
" a: 'abc',\n" &
|
||||
" b: \"abc\",\n" &
|
||||
" c: abc\n" &
|
||||
" }\n" &
|
||||
"blockChild:\n" &
|
||||
" a: \"a\\\nc\"\n" &
|
||||
" a: \"a\\nc\"\n" &
|
||||
" b: \"abc\"\n" &
|
||||
" c: \"ab:\"\n", output
|
||||
|
|
@ -53,7 +53,7 @@ suite "Presenter":
|
|||
|
||||
test "Forced multiline flow sequence":
|
||||
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":
|
||||
var input = inputSingle(startMapEvent(), scalarEvent("1"), scalarEvent("2"), endMapEvent())
|
||||
|
|
|
@ -33,7 +33,8 @@ proc setMinimalStyle*(dumper: var Dumper) =
|
|||
suppressAttrs: false,
|
||||
quoting: sqJson,
|
||||
condenseFlow: true,
|
||||
explicitKeys: false
|
||||
explicitKeys: false,
|
||||
maxLineLength: none(int)
|
||||
)
|
||||
dumper.serialization = SerializationOptions(
|
||||
tagStyle: tsNone,
|
||||
|
|
|
@ -1243,7 +1243,6 @@ proc recGenFieldRepresenters(
|
|||
))
|
||||
when `fieldAccessor`.hasCustomPragma(scalar):
|
||||
ctx.overridingScalarStyle = `fieldAccessor`.getCustomPragmaVal(scalar)
|
||||
echo "set scalar style to ", $ctx.overridingScalarStyle
|
||||
when `fieldAccessor`.hasCustomPragma(collection):
|
||||
ctx.overridingCollectionStyle = `fieldAccessor`.getCustomPragmaVal(collection)
|
||||
ctx.representChild(`fieldAccessor`)
|
||||
|
@ -1281,7 +1280,6 @@ proc recGenFieldRepresenters(
|
|||
))
|
||||
when `itemAccessor`.hasCustomPragma(scalar):
|
||||
ctx.overridingScalarStyle = `itemAccessor`.getCustomPragmaVal(scalar)
|
||||
echo "set scalar style to ", $ctx.overridingScalarStyle
|
||||
when `itemAccessor`.hasCustomPragma(collection):
|
||||
ctx.overridingCollectionStyle = `itemAccessor`.getCustomPragmaVal(collection)
|
||||
ctx.representChild(`itemAccessor`)
|
||||
|
@ -1307,7 +1305,6 @@ proc recGenFieldRepresenters(
|
|||
))
|
||||
when `childAccessor`.hasCustomPragma(scalar):
|
||||
ctx.overridingScalarStyle = `childAccessor`.getCustomPragmaVal(scalar)
|
||||
echo "set scalar style to ", $ctx.overridingScalarStyle
|
||||
when `childAccessor`.hasCustomPragma(collection):
|
||||
ctx.overridingCollectionStyle = `childAccessor`.getCustomPragmaVal(collection)
|
||||
ctx.representChild(`childAccessor`)
|
||||
|
|
|
@ -111,10 +111,14 @@ type
|
|||
needsWhitespace: int
|
||||
wroteDirectivesEnd: bool
|
||||
lastImplicitKeyLen: int
|
||||
cached: DeQue[Event]
|
||||
|
||||
ItemKind = enum
|
||||
ikCompactScalar, ikMultilineFlowScalar, ikBlockScalar, ikCollection
|
||||
|
||||
MapParseState = enum
|
||||
mpInitial, mpKey, mpValue, mpNeedBlock
|
||||
|
||||
proc level(ctx: var Context): var DumperLevel = ctx.levels[^1]
|
||||
|
||||
proc level(ctx: Context): DumperLevel = ctx.levels[^1]
|
||||
|
@ -595,7 +599,7 @@ proc startItem(
|
|||
of dFlowSequenceItem:
|
||||
ctx.append(',')
|
||||
ctx.whitespace(true)
|
||||
if not ctx.options.condenseFlow:
|
||||
if not ctx.level.singleLine:
|
||||
ctx.newline()
|
||||
t.write(repeat(' ', ctx.indentation))
|
||||
except CatchableError as ce:
|
||||
|
@ -644,6 +648,49 @@ proc nextItem(
|
|||
else:
|
||||
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(
|
||||
ctx: var Context,
|
||||
s : YamlStream,
|
||||
|
@ -651,12 +698,11 @@ proc doPresent(
|
|||
YamlPresenterJsonError, YamlPresenterOutputError,
|
||||
YamlStreamError
|
||||
].} =
|
||||
var
|
||||
cached = initDeQue[Event]()
|
||||
unclosedDoc = false
|
||||
var unclosedDoc = false
|
||||
ctx.cached = initDeQue[Event]()
|
||||
ctx.wroteDirectivesEnd = false
|
||||
while true:
|
||||
let item = nextItem(cached, s)
|
||||
let item = nextItem(ctx.cached, s)
|
||||
case item.kind
|
||||
of yamlStartStream: discard
|
||||
of yamlEndStream: break
|
||||
|
@ -801,6 +847,7 @@ proc doPresent(
|
|||
e.parent = ce
|
||||
raise e
|
||||
of yamlStartSeq:
|
||||
let (singleLine, _) = ctx.checkSingleLine(s, item, false)
|
||||
var nextState: DumperState
|
||||
if (ctx.levels.len > 0 and ctx.state.isFlow) or item.seqStyle == csFlow:
|
||||
nextState = dFlowSequenceStart
|
||||
|
@ -810,31 +857,13 @@ proc doPresent(
|
|||
else:
|
||||
case ctx.options.containers
|
||||
of cMixed:
|
||||
var length = 0
|
||||
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
|
||||
nextState = if singleLine: dFlowSequenceStart else: dBlockSequenceItem
|
||||
of cFlow: nextState = dFlowSequenceStart
|
||||
of cBlock:
|
||||
let next = s.peek()
|
||||
if next.kind == yamlEndSeq: nextState = dFlowSequenceStart
|
||||
else: nextState = dBlockSequenceItem
|
||||
nextState = if next.kind == yamlEndSeq: dFlowSequenceStart else: dBlockSequenceItem
|
||||
|
||||
var indentation = 0
|
||||
var singleLine = ctx.options.condenseFlow or ctx.options.newlines == nlNone
|
||||
|
||||
var wroteAnything = false
|
||||
if ctx.levels.len > 0: wroteAnything = ctx.state == dBlockImplicitMapKey
|
||||
|
||||
|
@ -844,6 +873,8 @@ proc doPresent(
|
|||
else:
|
||||
ctx.startItem(ikCollection)
|
||||
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)
|
||||
if wroteAttrs or (ctx.wroteDirectivesEnd and ctx.levels.len == 0):
|
||||
|
@ -854,12 +885,9 @@ proc doPresent(
|
|||
if wroteAttrs or ctx.wroteDirectivesEnd: ctx.safeNewline()
|
||||
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)
|
||||
of yamlStartMap:
|
||||
let (singleLine, mps) = ctx.checkSingleLine(s, item, true)
|
||||
var nextState: DumperState
|
||||
if (ctx.levels.len > 0 and ctx.state.isFlow) or item.mapStyle == csFlow:
|
||||
nextState = dFlowMapStart
|
||||
|
@ -869,27 +897,6 @@ proc doPresent(
|
|||
else:
|
||||
case ctx.options.containers
|
||||
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:
|
||||
nextState = dBlockMapValue
|
||||
elif ctx.levels.len == 0 or ctx.state == dBlockSequenceItem and item.emptyProperties:
|
||||
|
@ -903,8 +910,6 @@ proc doPresent(
|
|||
else: nextState = dBlockMapValue
|
||||
|
||||
var indentation = 0
|
||||
var singleLine = ctx.options.condenseFlow or ctx.options.newlines == nlNone
|
||||
|
||||
var wroteAnything = false
|
||||
if ctx.levels.len > 0: wroteAnything = ctx.state == dBlockImplicitMapKey
|
||||
|
||||
|
@ -914,6 +919,8 @@ proc doPresent(
|
|||
else:
|
||||
ctx.startItem(ikCollection)
|
||||
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)
|
||||
if wroteAttrs or (ctx.wroteDirectivesEnd and ctx.levels.len == 0):
|
||||
|
@ -924,10 +931,6 @@ proc doPresent(
|
|||
if wroteAttrs or ctx.wroteDirectivesEnd: ctx.safeNewline()
|
||||
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)
|
||||
of yamlEndSeq:
|
||||
yAssert ctx.levels.len > 0
|
||||
|
@ -937,7 +940,7 @@ proc doPresent(
|
|||
try:
|
||||
if not level.singleLine:
|
||||
ctx.newline()
|
||||
ctx.target.write(repeat(' ', ctx.indentation))
|
||||
ctx.target.write(repeat(' ', level.indentation - ctx.options.indentationStep))
|
||||
ctx.target.write(']')
|
||||
except CatchableError as ce:
|
||||
var e = newException(YamlPresenterOutputError, "")
|
||||
|
@ -954,7 +957,7 @@ proc doPresent(
|
|||
try:
|
||||
if not level.singleLine:
|
||||
ctx.safeNewline()
|
||||
ctx.target.write(repeat(' ', ctx.indentation))
|
||||
ctx.target.write(repeat(' ', level.indentation - ctx.options.indentationStep))
|
||||
ctx.append('}')
|
||||
except CatchableError as ce:
|
||||
var e = newException(YamlPresenterOutputError, "")
|
||||
|
|
Loading…
Reference in New Issue