summaryrefslogtreecommitdiff
path: root/reencode.go
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@datawire.io>2022-08-17 17:36:56 -0600
committerLuke Shumaker <lukeshu@datawire.io>2022-08-17 17:50:03 -0600
commit8fe464f2563ac35f7894041783debe0dfe82d528 (patch)
tree66d997b75d083957fc542f142625c505da133172 /reencode.go
parent494ad195bc31ce6a65f759544355801fe357c56d (diff)
reencode: Split handleRune in to pre- and post- parts
Diffstat (limited to 'reencode.go')
-rw-r--r--reencode.go102
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
}