diff options
-rw-r--r-- | reencode.go | 102 |
1 files changed, 58 insertions, 44 deletions
diff --git a/reencode.go b/reencode.go index 4c62cfc..ead7572 100644 --- a/reencode.go +++ b/reencode.go @@ -163,31 +163,30 @@ rehandle: // internal //////////////////////////////////////////////////////////////////// func (enc *ReEncoder) handleRune(c rune, t RuneType) error { - // whitespace - switch t { - case RuneTypeSpace: - if enc.Compact || enc.Indent != "" { - return nil - } + err, shouldHandle := enc.handleRunePre(c, t) + if err != nil { + return err } + if !shouldHandle { + return nil + } + return enc.handleRuneMain(c, t) +} - defer func() { - enc.lastNonSpace = t - }() - +// handle buffered things that need to happen before the new rune +// itself is handled. +func (enc *ReEncoder) handleRunePre(c rune, t RuneType) (error, bool) { // emit newlines between top-level values if enc.lastNonSpace == RuneTypeEOF { switch { case enc.wasNumber && t.IsNumber(): if err := enc.emitByte('\n'); err != nil { - return err + return err, false } case enc.Indent != "" && !enc.Compact: if err := enc.emitByte('\n'); err != nil { - return err + return err, false } - default: - // do nothing } } @@ -198,13 +197,13 @@ func (enc *ReEncoder) handleRune(c rune, t RuneType) error { case RuneTypeNumberFracDig: if c == '0' && enc.lastNonSpace == RuneTypeNumberFracDig { enc.fracZeros++ - return nil + return nil, false } fallthrough default: for enc.fracZeros > 0 { if err := enc.emitByte('0'); err != nil { - return err + return err, false } enc.fracZeros-- } @@ -214,49 +213,67 @@ func (enc *ReEncoder) handleRune(c rune, t RuneType) error { enc.expZero = true case RuneTypeNumberExpDig: if c == '0' && enc.expZero { - return nil + return nil, false } enc.expZero = false default: if enc.expZero { if err := enc.emitByte('0'); err != nil { - return err + return err, false } enc.expZero = false } } - // indent - switch t { - case RuneTypeObjectBeg, RuneTypeArrayBeg: - enc.curIndent++ - case RuneTypeObjectEnd, RuneTypeArrayEnd: - enc.curIndent-- - switch enc.lastNonSpace { + // whitespace + switch { + case enc.Compact: + if t == RuneTypeSpace { + return nil, false + } + case enc.Indent != "": + switch t { + case RuneTypeSpace: + // let us manage whitespace + return nil, false case RuneTypeObjectBeg, RuneTypeArrayBeg: - // collapse - default: - if err := enc.emitNlIndent(); err != nil { - return err + enc.curIndent++ + case RuneTypeObjectEnd, RuneTypeArrayEnd: + enc.curIndent-- + switch enc.lastNonSpace { + case RuneTypeObjectBeg, RuneTypeArrayBeg: + // collapse + default: + if err := enc.emitNlIndent(); err != nil { + return err, false + } } - } - case RuneTypeObjectColon: - if !enc.Compact && enc.Indent != "" { - if err := enc.emitByte(':'); err != nil { - return err + default: + switch enc.lastNonSpace { + case RuneTypeObjectBeg, RuneTypeObjectComma, RuneTypeArrayBeg, RuneTypeArrayComma: + if err := enc.emitNlIndent(); err != nil { + return err, false + } } - return enc.emitByte(' ') } - default: - switch enc.lastNonSpace { - case RuneTypeObjectBeg, RuneTypeObjectComma, RuneTypeArrayBeg, RuneTypeArrayComma: - if err := enc.emitNlIndent(); err != nil { - return err + if enc.lastNonSpace == RuneTypeObjectColon { + if err := enc.emitByte(' '); err != nil { + return err, false } } } - // main + return nil, true +} + +// handle the new rune itself, not buffered things +func (enc *ReEncoder) handleRuneMain(c rune, t RuneType) error { + defer func() { + if t != RuneTypeSpace { + enc.lastNonSpace = t + } + }() + switch t { case RuneTypeStringChar: @@ -333,9 +350,6 @@ func (enc *ReEncoder) emit(n int, err error) error { } func (enc *ReEncoder) emitNlIndent() error { - if enc.Compact || enc.Indent == "" { - return nil - } if err := enc.emitByte('\n'); err != nil { return err } |