Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
// The API is created from Config by Froze.
type Config struct {
IndentionStep int
IndentionChar byte
MarshalFloatWith6Digits bool
EscapeHTML bool
SortMapKeys bool
Expand Down Expand Up @@ -47,26 +48,30 @@ type API interface {
// ConfigDefault the default API
var ConfigDefault = Config{
EscapeHTML: true,
IndentionChar: ' ',
}.Froze()

// ConfigCompatibleWithStandardLibrary tries to be 100% compatible with standard library behavior
var ConfigCompatibleWithStandardLibrary = Config{
EscapeHTML: true,
SortMapKeys: true,
ValidateJsonRawMessage: true,
IndentionChar: ' ',
}.Froze()

// ConfigFastest marshals float with only 6 digits precision
var ConfigFastest = Config{
EscapeHTML: false,
MarshalFloatWith6Digits: true, // will lose precession
ObjectFieldMustBeSimpleString: true, // do not unescape object field
IndentionChar: ' ',
}.Froze()

type frozenConfig struct {
configBeforeFrozen Config
sortMapKeys bool
indentionStep int
indentionChar byte
objectFieldMustBeSimpleString bool
onlyTaggedField bool
disallowUnknownFields bool
Expand Down Expand Up @@ -125,6 +130,7 @@ func (cfg Config) Froze() API {
api := &frozenConfig{
sortMapKeys: cfg.SortMapKeys,
indentionStep: cfg.IndentionStep,
indentionChar: cfg.IndentionChar,
objectFieldMustBeSimpleString: cfg.ObjectFieldMustBeSimpleString,
onlyTaggedField: cfg.OnlyTaggedField,
disallowUnknownFields: cfg.DisallowUnknownFields,
Expand Down Expand Up @@ -300,15 +306,26 @@ func (cfg *frozenConfig) Marshal(v interface{}) ([]byte, error) {
}

func (cfg *frozenConfig) MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
var useTabs bool
if prefix != "" {
panic("prefix is not supported")
}
// some rudimentary error checking
newCfg := cfg.configBeforeFrozen
newCfg.IndentionChar = ' '
for _, r := range indent {
if r != ' ' {
panic("indent can only be space")
if r != ' ' && r != '\t' {
panic("indent can only be space or tabs")
}
if r == ' ' && useTabs {
panic("indent cannot be mixed space and tabs")
}
if r == '\t' {
useTabs = true
newCfg.IndentionChar = '\t'
}
}
newCfg := cfg.configBeforeFrozen

newCfg.IndentionStep = len(indent)
return newCfg.frozeWithCacheReuse().Marshal(v)
}
Expand Down
24 changes: 24 additions & 0 deletions config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package jsoniter

import (
"testing"
"github.com/stretchr/testify/assert"
)

func TestFrozenConfig_MarshalIndentErrors(t *testing.T) {
var panicOccured interface{} = nil

defer func() {
panicOccured = recover()
}()
_, err := MarshalIndent(`{"foo":"bar"}`, "", "\n\n")

assert.NoError(t, err)
assert.NotNil(t, panicOccured, "MarshalIndent should panic due to invalid indent chars")

panicOccured = nil
_, err = MarshalIndent(`{"foo":"bar"}`, "", " \t ")
panicOccured = recover()
assert.NoError(t, err)
assert.NotNil(t, panicOccured, "MarshalIndent should panic due to mixed spaces and tabs")
}
2 changes: 1 addition & 1 deletion stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,6 @@ func (stream *Stream) writeIndention(delta int) {
stream.writeByte('\n')
toWrite := stream.indention - delta
for i := 0; i < toWrite; i++ {
stream.buf = append(stream.buf, ' ')
stream.buf = append(stream.buf, stream.cfg.indentionChar)
}
}
9 changes: 8 additions & 1 deletion stream_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,18 @@ func Test_writeBytes_should_grow_buffer(t *testing.T) {

func Test_writeIndention_should_grow_buffer(t *testing.T) {
should := require.New(t)
stream := NewStream(Config{IndentionStep: 2}.Froze(), nil, 1)
stream := NewStream(Config{IndentionStep: 2, IndentionChar:' '}.Froze(), nil, 1)
stream.WriteVal([]int{1, 2, 3})
should.Equal("[\n 1,\n 2,\n 3\n]", string(stream.Buffer()))
}

func Test_writeIndention_with_tabs_should_grow_buffer(t *testing.T) {
should := require.New(t)
stream := NewStream(Config{IndentionStep: 2, IndentionChar: '\t'}.Froze(), nil, 1)
stream.WriteVal([]int{1, 2, 3})
should.Equal("[\n 1,\n 2,\n 3\n]", string(stream.Buffer()))
}

func Test_writeRaw_should_grow_buffer(t *testing.T) {
should := require.New(t)
stream := NewStream(ConfigDefault, nil, 1)
Expand Down