Add indentation setting for Encoder (#386)

Fixes #371
This commit is contained in:
x-hgg-x
2020-05-04 19:21:22 +02:00
committed by GitHub
parent cc3100c329
commit 82a6a1977d
3 changed files with 59 additions and 11 deletions
+22 -7
View File
@@ -218,17 +218,19 @@ type Encoder struct {
col int col int
order marshalOrder order marshalOrder
promoteAnon bool promoteAnon bool
indentation string
} }
// NewEncoder returns a new encoder that writes to w. // NewEncoder returns a new encoder that writes to w.
func NewEncoder(w io.Writer) *Encoder { func NewEncoder(w io.Writer) *Encoder {
return &Encoder{ return &Encoder{
w: w, w: w,
encOpts: encOptsDefaults, encOpts: encOptsDefaults,
annotation: annotationDefault, annotation: annotationDefault,
line: 0, line: 0,
col: 1, col: 1,
order: OrderAlphabetical, order: OrderAlphabetical,
indentation: " ",
} }
} }
@@ -280,6 +282,12 @@ func (e *Encoder) Order(ord marshalOrder) *Encoder {
return e return e
} }
// Indentation allows to change indentation when marshalling.
func (e *Encoder) Indentation(indent string) *Encoder {
e.indentation = indent
return e
}
// SetTagName allows changing default tag "toml" // SetTagName allows changing default tag "toml"
func (e *Encoder) SetTagName(v string) *Encoder { func (e *Encoder) SetTagName(v string) *Encoder {
e.tag = v e.tag = v
@@ -318,6 +326,13 @@ func (e *Encoder) PromoteAnonymous(promote bool) *Encoder {
} }
func (e *Encoder) marshal(v interface{}) ([]byte, error) { func (e *Encoder) marshal(v interface{}) ([]byte, error) {
// Check if indentation is valid
for _, char := range e.indentation {
if !(char == ' ' || char == '\t') {
return []byte{}, fmt.Errorf("invalid indentation: must only contains space or tab characters")
}
}
mtype := reflect.TypeOf(v) mtype := reflect.TypeOf(v)
if mtype == nil { if mtype == nil {
return []byte{}, errors.New("nil cannot be marshaled to TOML") return []byte{}, errors.New("nil cannot be marshaled to TOML")
@@ -349,7 +364,7 @@ func (e *Encoder) marshal(v interface{}) ([]byte, error) {
} }
var buf bytes.Buffer var buf bytes.Buffer
_, err = t.writeToOrdered(&buf, "", "", 0, e.arraysOneElementPerLine, e.order, false) _, err = t.writeToOrdered(&buf, "", "", 0, e.arraysOneElementPerLine, e.order, e.indentation, false)
return buf.Bytes(), err return buf.Bytes(), err
} }
+33
View File
@@ -44,6 +44,19 @@ Zstring = "Hello"
String2 = "One" String2 = "One"
`) `)
var basicTestTomlCustomIndentation = []byte(`Ystrlist = ["Howdy","Hey There"]
Zstring = "Hello"
[[Wsublist]]
String2 = "Two"
[[Wsublist]]
String2 = "Three"
[Xsubdoc]
String2 = "One"
`)
var basicTestTomlOrdered = []byte(`Zstring = "Hello" var basicTestTomlOrdered = []byte(`Zstring = "Hello"
Ystrlist = ["Howdy","Hey There"] Ystrlist = ["Howdy","Hey There"]
@@ -207,6 +220,26 @@ func TestBasicMarshal(t *testing.T) {
} }
} }
func TestBasicMarshalCustomIndentation(t *testing.T) {
var result bytes.Buffer
err := NewEncoder(&result).Indentation("\t").Encode(basicTestData)
if err != nil {
t.Fatal(err)
}
expected := basicTestTomlCustomIndentation
if !bytes.Equal(result.Bytes(), expected) {
t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result.Bytes())
}
}
func TestBasicMarshalWrongIndentation(t *testing.T) {
var result bytes.Buffer
err := NewEncoder(&result).Indentation(" \n").Encode(basicTestData)
if err.Error() != "invalid indentation: must only contains space or tab characters" {
t.Error("expect err:invalid indentation: must only contains space or tab characters but got:", err)
}
}
func TestBasicMarshalOrdered(t *testing.T) { func TestBasicMarshalOrdered(t *testing.T) {
var result bytes.Buffer var result bytes.Buffer
err := NewEncoder(&result).Order(OrderPreserve).Encode(basicTestData) err := NewEncoder(&result).Order(OrderPreserve).Encode(basicTestData)
+4 -4
View File
@@ -282,10 +282,10 @@ func sortAlphabetical(t *Tree) (vals []sortNode) {
} }
func (t *Tree) writeTo(w io.Writer, indent, keyspace string, bytesCount int64, arraysOneElementPerLine bool) (int64, error) { func (t *Tree) writeTo(w io.Writer, indent, keyspace string, bytesCount int64, arraysOneElementPerLine bool) (int64, error) {
return t.writeToOrdered(w, indent, keyspace, bytesCount, arraysOneElementPerLine, OrderAlphabetical, false) return t.writeToOrdered(w, indent, keyspace, bytesCount, arraysOneElementPerLine, OrderAlphabetical, " ", false)
} }
func (t *Tree) writeToOrdered(w io.Writer, indent, keyspace string, bytesCount int64, arraysOneElementPerLine bool, ord marshalOrder, parentCommented bool) (int64, error) { func (t *Tree) writeToOrdered(w io.Writer, indent, keyspace string, bytesCount int64, arraysOneElementPerLine bool, ord marshalOrder, indentString string, parentCommented bool) (int64, error) {
var orderedVals []sortNode var orderedVals []sortNode
switch ord { switch ord {
@@ -335,7 +335,7 @@ func (t *Tree) writeToOrdered(w io.Writer, indent, keyspace string, bytesCount i
if err != nil { if err != nil {
return bytesCount, err return bytesCount, err
} }
bytesCount, err = node.writeToOrdered(w, indent+" ", combinedKey, bytesCount, arraysOneElementPerLine, ord, parentCommented || t.commented || tv.commented) bytesCount, err = node.writeToOrdered(w, indent+indentString, combinedKey, bytesCount, arraysOneElementPerLine, ord, indentString, parentCommented || t.commented || tv.commented)
if err != nil { if err != nil {
return bytesCount, err return bytesCount, err
} }
@@ -351,7 +351,7 @@ func (t *Tree) writeToOrdered(w io.Writer, indent, keyspace string, bytesCount i
return bytesCount, err return bytesCount, err
} }
bytesCount, err = subTree.writeToOrdered(w, indent+" ", combinedKey, bytesCount, arraysOneElementPerLine, ord, parentCommented || t.commented || subTree.commented) bytesCount, err = subTree.writeToOrdered(w, indent+indentString, combinedKey, bytesCount, arraysOneElementPerLine, ord, indentString, parentCommented || t.commented || subTree.commented)
if err != nil { if err != nil {
return bytesCount, err return bytesCount, err
} }