+2
-2
@@ -367,7 +367,7 @@ 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
|
// Check if indentation is valid
|
||||||
for _, char := range e.indentation {
|
for _, char := range e.indentation {
|
||||||
if !(char == ' ' || char == '\t') {
|
if !isSpace(char) {
|
||||||
return []byte{}, fmt.Errorf("invalid indentation: must only contains space or tab characters")
|
return []byte{}, fmt.Errorf("invalid indentation: must only contains space or tab characters")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -475,7 +475,7 @@ func (e *Encoder) valueToTree(mtype reflect.Type, mval reflect.Value) (*Tree, er
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if e.quoteMapKeys {
|
if e.quoteMapKeys {
|
||||||
keyStr, err := tomlValueStringRepresentation(key.String(), "", "", OrderPreserve, e.arraysOneElementPerLine)
|
keyStr, err := tomlValueStringRepresentation(key.String(), "", "", e.order, e.arraysOneElementPerLine)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
+85
-33
@@ -31,7 +31,7 @@ var basicTestData = basicMarshalTestStruct{
|
|||||||
SubList: []basicMarshalTestSubStruct{{"Two"}, {"Three"}},
|
SubList: []basicMarshalTestSubStruct{{"Two"}, {"Three"}},
|
||||||
}
|
}
|
||||||
|
|
||||||
var basicTestToml = []byte(`Ystrlist = ["Howdy","Hey There"]
|
var basicTestToml = []byte(`Ystrlist = ["Howdy", "Hey There"]
|
||||||
Zstring = "Hello"
|
Zstring = "Hello"
|
||||||
|
|
||||||
[[Wsublist]]
|
[[Wsublist]]
|
||||||
@@ -44,7 +44,7 @@ Zstring = "Hello"
|
|||||||
String2 = "One"
|
String2 = "One"
|
||||||
`)
|
`)
|
||||||
|
|
||||||
var basicTestTomlCustomIndentation = []byte(`Ystrlist = ["Howdy","Hey There"]
|
var basicTestTomlCustomIndentation = []byte(`Ystrlist = ["Howdy", "Hey There"]
|
||||||
Zstring = "Hello"
|
Zstring = "Hello"
|
||||||
|
|
||||||
[[Wsublist]]
|
[[Wsublist]]
|
||||||
@@ -58,7 +58,7 @@ Zstring = "Hello"
|
|||||||
`)
|
`)
|
||||||
|
|
||||||
var basicTestTomlOrdered = []byte(`Zstring = "Hello"
|
var basicTestTomlOrdered = []byte(`Zstring = "Hello"
|
||||||
Ystrlist = ["Howdy","Hey There"]
|
Ystrlist = ["Howdy", "Hey There"]
|
||||||
|
|
||||||
[Xsubdoc]
|
[Xsubdoc]
|
||||||
String2 = "One"
|
String2 = "One"
|
||||||
@@ -82,12 +82,12 @@ var marshalTestToml = []byte(`title = "TOML Marshal Testing"
|
|||||||
uint = 5001
|
uint = 5001
|
||||||
|
|
||||||
[basic_lists]
|
[basic_lists]
|
||||||
bools = [true,false,true]
|
bools = [true, false, true]
|
||||||
dates = [1979-05-27T07:32:00Z,1980-05-27T07:32:00Z]
|
dates = [1979-05-27T07:32:00Z, 1980-05-27T07:32:00Z]
|
||||||
floats = [12.3,45.6,78.9]
|
floats = [12.3, 45.6, 78.9]
|
||||||
ints = [8001,8001,8002]
|
ints = [8001, 8001, 8002]
|
||||||
strings = ["One","Two","Three"]
|
strings = ["One", "Two", "Three"]
|
||||||
uints = [5002,5003]
|
uints = [5002, 5003]
|
||||||
|
|
||||||
[basic_map]
|
[basic_map]
|
||||||
one = "one"
|
one = "one"
|
||||||
@@ -114,12 +114,12 @@ var marshalTestToml = []byte(`title = "TOML Marshal Testing"
|
|||||||
var marshalOrderPreserveToml = []byte(`title = "TOML Marshal Testing"
|
var marshalOrderPreserveToml = []byte(`title = "TOML Marshal Testing"
|
||||||
|
|
||||||
[basic_lists]
|
[basic_lists]
|
||||||
floats = [12.3,45.6,78.9]
|
floats = [12.3, 45.6, 78.9]
|
||||||
bools = [true,false,true]
|
bools = [true, false, true]
|
||||||
dates = [1979-05-27T07:32:00Z,1980-05-27T07:32:00Z]
|
dates = [1979-05-27T07:32:00Z, 1980-05-27T07:32:00Z]
|
||||||
ints = [8001,8001,8002]
|
ints = [8001, 8001, 8002]
|
||||||
uints = [5002,5003]
|
uints = [5002, 5003]
|
||||||
strings = ["One","Two","Three"]
|
strings = ["One", "Two", "Three"]
|
||||||
|
|
||||||
[[subdocptrs]]
|
[[subdocptrs]]
|
||||||
name = "Second"
|
name = "Second"
|
||||||
@@ -913,8 +913,8 @@ var nestedTestData = nestedMarshalTestStruct{
|
|||||||
StringPtr: &strPtr2,
|
StringPtr: &strPtr2,
|
||||||
}
|
}
|
||||||
|
|
||||||
var nestedTestToml = []byte(`String = [["Five","Six"],["One","Two"]]
|
var nestedTestToml = []byte(`String = [["Five", "Six"], ["One", "Two"]]
|
||||||
StringPtr = [["Three","Four"]]
|
StringPtr = [["Three", "Four"]]
|
||||||
`)
|
`)
|
||||||
|
|
||||||
func TestNestedMarshal(t *testing.T) {
|
func TestNestedMarshal(t *testing.T) {
|
||||||
@@ -1491,7 +1491,7 @@ type structArrayNoTag struct {
|
|||||||
func TestMarshalArray(t *testing.T) {
|
func TestMarshalArray(t *testing.T) {
|
||||||
expected := []byte(`
|
expected := []byte(`
|
||||||
[A]
|
[A]
|
||||||
B = [1,2,3]
|
B = [1, 2, 3]
|
||||||
C = [1]
|
C = [1]
|
||||||
`)
|
`)
|
||||||
|
|
||||||
@@ -1988,6 +1988,58 @@ func TestMarshalSlicePointer(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMarshalNestedArrayInlineTables(t *testing.T) {
|
||||||
|
type table struct {
|
||||||
|
Value1 int `toml:"ZValue1"`
|
||||||
|
Value2 int `toml:"YValue2"`
|
||||||
|
Value3 int `toml:"XValue3"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type nestedTable struct {
|
||||||
|
Table table
|
||||||
|
}
|
||||||
|
|
||||||
|
nestedArray := struct {
|
||||||
|
Simple [][]table
|
||||||
|
SimplePointer *[]*[]table
|
||||||
|
Nested [][]nestedTable
|
||||||
|
NestedPointer *[]*[]nestedTable
|
||||||
|
}{
|
||||||
|
Simple: [][]table{{{Value1: 1}, {Value1: 10}}},
|
||||||
|
SimplePointer: &[]*[]table{{{Value2: 2}}},
|
||||||
|
Nested: [][]nestedTable{{{Table: table{Value3: 3}}}},
|
||||||
|
NestedPointer: &[]*[]nestedTable{{{Table: table{Value3: -3}}}},
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedPreserve := `Simple = [[{ ZValue1 = 1, YValue2 = 0, XValue3 = 0 }, { ZValue1 = 10, YValue2 = 0, XValue3 = 0 }]]
|
||||||
|
SimplePointer = [[{ ZValue1 = 0, YValue2 = 2, XValue3 = 0 }]]
|
||||||
|
Nested = [[{ Table = { ZValue1 = 0, YValue2 = 0, XValue3 = 3 } }]]
|
||||||
|
NestedPointer = [[{ Table = { ZValue1 = 0, YValue2 = 0, XValue3 = -3 } }]]
|
||||||
|
`
|
||||||
|
|
||||||
|
expectedAlphabetical := `Nested = [[{ Table = { XValue3 = 3, YValue2 = 0, ZValue1 = 0 } }]]
|
||||||
|
NestedPointer = [[{ Table = { XValue3 = -3, YValue2 = 0, ZValue1 = 0 } }]]
|
||||||
|
Simple = [[{ XValue3 = 0, YValue2 = 0, ZValue1 = 1 }, { XValue3 = 0, YValue2 = 0, ZValue1 = 10 }]]
|
||||||
|
SimplePointer = [[{ XValue3 = 0, YValue2 = 2, ZValue1 = 0 }]]
|
||||||
|
`
|
||||||
|
|
||||||
|
var bufPreserve bytes.Buffer
|
||||||
|
if err := NewEncoder(&bufPreserve).Order(OrderPreserve).Encode(nestedArray); err != nil {
|
||||||
|
t.Fatalf("unexpected error: %s", err.Error())
|
||||||
|
}
|
||||||
|
if !bytes.Equal(bufPreserve.Bytes(), []byte(expectedPreserve)) {
|
||||||
|
t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expectedPreserve, bufPreserve.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
var bufAlphabetical bytes.Buffer
|
||||||
|
if err := NewEncoder(&bufAlphabetical).Order(OrderAlphabetical).Encode(nestedArray); err != nil {
|
||||||
|
t.Fatalf("unexpected error: %s", err.Error())
|
||||||
|
}
|
||||||
|
if !bytes.Equal(bufAlphabetical.Bytes(), []byte(expectedAlphabetical)) {
|
||||||
|
t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expectedAlphabetical, bufAlphabetical.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type testDuration struct {
|
type testDuration struct {
|
||||||
Nanosec time.Duration `toml:"nanosec"`
|
Nanosec time.Duration `toml:"nanosec"`
|
||||||
Microsec1 time.Duration `toml:"microsec1"`
|
Microsec1 time.Duration `toml:"microsec1"`
|
||||||
@@ -2602,7 +2654,7 @@ func TestMarshalArrays(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
XY: [2]int{1, 2},
|
XY: [2]int{1, 2},
|
||||||
},
|
},
|
||||||
Expected: `XY = [1,2]
|
Expected: `XY = [1, 2]
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -2611,7 +2663,7 @@ func TestMarshalArrays(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
XY: [1][2]int{{1, 2}},
|
XY: [1][2]int{{1, 2}},
|
||||||
},
|
},
|
||||||
Expected: `XY = [[1,2]]
|
Expected: `XY = [[1, 2]]
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -2620,7 +2672,7 @@ func TestMarshalArrays(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
XY: [1][]int{{1, 2}},
|
XY: [1][]int{{1, 2}},
|
||||||
},
|
},
|
||||||
Expected: `XY = [[1,2]]
|
Expected: `XY = [[1, 2]]
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -2629,7 +2681,7 @@ func TestMarshalArrays(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
XY: [][2]int{{1, 2}},
|
XY: [][2]int{{1, 2}},
|
||||||
},
|
},
|
||||||
Expected: `XY = [[1,2]]
|
Expected: `XY = [[1, 2]]
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -3047,7 +3099,7 @@ func TestMarshalInterface(t *testing.T) {
|
|||||||
InterfacePointerField *interface{}
|
InterfacePointerField *interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
expected := []byte(`ArrayField = [1,2,3]
|
expected := []byte(`ArrayField = [1, 2, 3]
|
||||||
InterfacePointerField = "hello world"
|
InterfacePointerField = "hello world"
|
||||||
PrimitiveField = "string"
|
PrimitiveField = "string"
|
||||||
|
|
||||||
@@ -3420,22 +3472,22 @@ func TestMarshalMixedTypeArray(t *testing.T) {
|
|||||||
ArrayField []interface{}
|
ArrayField []interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
expected := []byte(`ArrayField = [3.14,100,true,"hello world",{IntField = 100,StrField = "inner1"},[{IntField = 200,StrField = "inner2"},{IntField = 300,StrField = "inner3"}]]
|
expected := []byte(`ArrayField = [3.14, 100, true, "hello world", { IntField = 100, StrField = "inner1" }, [{ IntField = 200, StrField = "inner2" }, { IntField = 300, StrField = "inner3" }]]
|
||||||
`)
|
`)
|
||||||
|
|
||||||
if result, err := Marshal(TestStruct{
|
if result, err := Marshal(TestStruct{
|
||||||
ArrayField:[]interface{}{
|
ArrayField: []interface{}{
|
||||||
3.14,
|
3.14,
|
||||||
100,
|
100,
|
||||||
true,
|
true,
|
||||||
"hello world",
|
"hello world",
|
||||||
InnerStruct{
|
InnerStruct{
|
||||||
IntField:100,
|
IntField: 100,
|
||||||
StrField:"inner1",
|
StrField: "inner1",
|
||||||
},
|
},
|
||||||
[]InnerStruct{
|
[]InnerStruct{
|
||||||
{IntField:200,StrField:"inner2"},
|
{IntField: 200, StrField: "inner2"},
|
||||||
{IntField:300,StrField:"inner3"},
|
{IntField: 300, StrField: "inner3"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}); err == nil {
|
}); err == nil {
|
||||||
@@ -3457,17 +3509,17 @@ func TestUnmarshalMixedTypeArray(t *testing.T) {
|
|||||||
|
|
||||||
actual := TestStruct{}
|
actual := TestStruct{}
|
||||||
expected := TestStruct{
|
expected := TestStruct{
|
||||||
ArrayField:[]interface{}{
|
ArrayField: []interface{}{
|
||||||
3.14,
|
3.14,
|
||||||
int64(100),
|
int64(100),
|
||||||
true,
|
true,
|
||||||
"hello world",
|
"hello world",
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"Field":"inner1",
|
"Field": "inner1",
|
||||||
},
|
},
|
||||||
[]map[string]interface{}{
|
[]map[string]interface{}{
|
||||||
{"Field":"inner2"},
|
{"Field": "inner2"},
|
||||||
{"Field":"inner3"},
|
{"Field": "inner3"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -919,10 +919,10 @@ func TestTomlValueStringRepresentation(t *testing.T) {
|
|||||||
{"\b\t\n\f\r\"\\", "\"\\b\\t\\n\\f\\r\\\"\\\\\""},
|
{"\b\t\n\f\r\"\\", "\"\\b\\t\\n\\f\\r\\\"\\\\\""},
|
||||||
{"\x05", "\"\\u0005\""},
|
{"\x05", "\"\\u0005\""},
|
||||||
{time.Date(1979, time.May, 27, 7, 32, 0, 0, time.UTC), "1979-05-27T07:32:00Z"},
|
{time.Date(1979, time.May, 27, 7, 32, 0, 0, time.UTC), "1979-05-27T07:32:00Z"},
|
||||||
{[]interface{}{"gamma", "delta"}, "[\"gamma\",\"delta\"]"},
|
{[]interface{}{"gamma", "delta"}, "[\"gamma\", \"delta\"]"},
|
||||||
{nil, ""},
|
{nil, ""},
|
||||||
} {
|
} {
|
||||||
result, err := tomlValueStringRepresentation(item.Value, "", "", OrderPreserve, false)
|
result, err := tomlValueStringRepresentation(item.Value, "", "", OrderAlphabetical, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Test %d - unexpected error: %s", idx, err)
|
t.Errorf("Test %d - unexpected error: %s", idx, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ func TestTreeCreateToTreeInvalidTableGroupType(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestRoundTripArrayOfTables(t *testing.T) {
|
func TestRoundTripArrayOfTables(t *testing.T) {
|
||||||
orig := "\n[[stuff]]\n name = \"foo\"\n things = [\"a\",\"b\"]\n"
|
orig := "\n[[stuff]]\n name = \"foo\"\n things = [\"a\", \"b\"]\n"
|
||||||
tree, err := Load(orig)
|
tree, err := Load(orig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %s", err)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
|
|||||||
+9
-21
@@ -105,7 +105,6 @@ func encodeTomlString(value string) string {
|
|||||||
|
|
||||||
func tomlTreeStringRepresentation(t *Tree, ord marshalOrder) (string, error) {
|
func tomlTreeStringRepresentation(t *Tree, ord marshalOrder) (string, error) {
|
||||||
var orderedVals []sortNode
|
var orderedVals []sortNode
|
||||||
|
|
||||||
switch ord {
|
switch ord {
|
||||||
case OrderPreserve:
|
case OrderPreserve:
|
||||||
orderedVals = sortByLines(t)
|
orderedVals = sortByLines(t)
|
||||||
@@ -113,29 +112,18 @@ func tomlTreeStringRepresentation(t *Tree, ord marshalOrder) (string, error) {
|
|||||||
orderedVals = sortAlphabetical(t)
|
orderedVals = sortAlphabetical(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
stringBuffer := bytes.Buffer{}
|
var values []string
|
||||||
stringBuffer.WriteString(`{`)
|
for _, node := range orderedVals {
|
||||||
first := true
|
k := node.key
|
||||||
for i := range orderedVals {
|
v := t.values[k]
|
||||||
v := t.values[orderedVals[i].key]
|
|
||||||
quotedKey := quoteKeyIfNeeded(orderedVals[i].key)
|
repr, err := tomlValueStringRepresentation(v, "", "", ord, false)
|
||||||
valueStr, err := tomlValueStringRepresentation(v, "", "", ord, false)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
if first {
|
values = append(values, quoteKeyIfNeeded(k)+" = "+repr)
|
||||||
first = false
|
|
||||||
} else {
|
|
||||||
stringBuffer.WriteString(`,`)
|
|
||||||
}
|
|
||||||
|
|
||||||
stringBuffer.WriteString(quotedKey)
|
|
||||||
stringBuffer.WriteString(" = ")
|
|
||||||
stringBuffer.WriteString(valueStr)
|
|
||||||
}
|
}
|
||||||
stringBuffer.WriteString(`}`)
|
return "{ " + strings.Join(values, ", ") + " }", nil
|
||||||
|
|
||||||
return stringBuffer.String(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func tomlValueStringRepresentation(v interface{}, commented string, indent string, ord marshalOrder, arraysOneElementPerLine bool) (string, error) {
|
func tomlValueStringRepresentation(v interface{}, commented string, indent string, ord marshalOrder, arraysOneElementPerLine bool) (string, error) {
|
||||||
@@ -224,7 +212,7 @@ func tomlValueStringRepresentation(v interface{}, commented string, indent strin
|
|||||||
|
|
||||||
return stringBuffer.String(), nil
|
return stringBuffer.String(), nil
|
||||||
}
|
}
|
||||||
return "[" + strings.Join(values, ",") + "]", nil
|
return "[" + strings.Join(values, ", ") + "]", nil
|
||||||
}
|
}
|
||||||
return "", fmt.Errorf("unsupported value type %T: %v", v, v)
|
return "", fmt.Errorf("unsupported value type %T: %v", v, v)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user