diff --git a/README.md b/README.md index d622596..8279102 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ This library supports TOML version Go-toml provides the following features for using data parsed from TOML documents: * Load TOML documents from files and string data -* Easily navigate TOML structure using TomlTree +* Easily navigate TOML structure using Tree * Line & column position data for all parsed elements * [Query support similar to JSON-Path](query/) * Syntax errors contain line and column numbers @@ -61,7 +61,7 @@ if err != nil { password := config.Get("postgres.password").(string) // or using an intermediate object - configTree := config.Get("postgres").(*toml.TomlTree) + configTree := config.Get("postgres").(*toml.Tree) user = configTree.Get("user").(string) password = configTree.Get("password").(string) fmt.Println("User is ", user, ". Password is ", password) diff --git a/cmd/test_program.go b/cmd/test_program.go index 5829344..73077f6 100644 --- a/cmd/test_program.go +++ b/cmd/test_program.go @@ -41,16 +41,16 @@ func translate(tomlData interface{}) interface{} { typed[k] = translate(v) } return typed - case *toml.TomlTree: + case *toml.Tree: return translate(*orig) - case toml.TomlTree: + case toml.Tree: keys := orig.Keys() typed := make(map[string]interface{}, len(keys)) for _, k := range keys { typed[k] = translate(orig.GetPath([]string{k})) } return typed - case []*toml.TomlTree: + case []*toml.Tree: typed := make([]map[string]interface{}, len(orig)) for i, v := range orig { typed[i] = translate(v).(map[string]interface{}) diff --git a/cmd/tomljson/main.go b/cmd/tomljson/main.go index 7e9dc46..8bfe462 100644 --- a/cmd/tomljson/main.go +++ b/cmd/tomljson/main.go @@ -57,7 +57,7 @@ func reader(r io.Reader) (string, error) { return mapToJSON(tree) } -func mapToJSON(tree *toml.TomlTree) (string, error) { +func mapToJSON(tree *toml.Tree) (string, error) { treeMap := tree.ToMap() bytes, err := json.MarshalIndent(treeMap, "", " ") if err != nil { diff --git a/doc.go b/doc.go index 395d4f4..cfa5e4a 100644 --- a/doc.go +++ b/doc.go @@ -13,14 +13,14 @@ // // load TOML data stored in a string // tree, err := toml.Load(stringContainingTomlData) // -// Either way, the result is a TomlTree object that can be used to navigate the +// Either way, the result is a Tree object that can be used to navigate the // structure and data within the original document. // // -// Getting data from the TomlTree +// Getting data from the Tree // // After parsing TOML data with Load() or LoadFile(), use the Has() and Get() -// methods on the returned TomlTree, to find your way through the document data. +// methods on the returned Tree, to find your way through the document data. // // if tree.Has("foo") { // fmt.Println("foo is:", tree.Get("foo")) @@ -50,11 +50,11 @@ // tree.GetPath([]string{"foo","bar","baz"}) // // Note that this is distinct from the heavyweight query syntax supported by -// TomlTree.Query() and the Query() struct (see below). +// Tree.Query() and the Query() struct (see below). // // Position Support // -// Each element within the TomlTree is stored with position metadata, which is +// Each element within the Tree is stored with position metadata, which is // invaluable for providing semantic feedback to a user. This helps in // situations where the TOML file parses correctly, but contains data that is // not correct for the application. In such cases, an error message can be diff --git a/doc_test.go b/doc_test.go index 6553e4e..31b4f40 100644 --- a/doc_test.go +++ b/doc_test.go @@ -17,7 +17,7 @@ func Example_comprehensiveExample() { password := config.Get("postgres.password").(string) // or using an intermediate object - configTree := config.Get("postgres").(*TomlTree) + configTree := config.Get("postgres").(*Tree) user = configTree.Get("user").(string) password = configTree.Get("password").(string) fmt.Println("User is ", user, ". Password is ", password) diff --git a/marshal.go b/marshal.go index 1444006..358425a 100644 --- a/marshal.go +++ b/marshal.go @@ -10,14 +10,14 @@ import ( ) /* -TomlTree structural types and corresponding marshal types +Tree structural types and corresponding marshal types ------------------------------------------------------------------------------- -*TomlTree (*)struct, (*)map[string]interface{} -[]*TomlTree (*)[](*)struct, (*)[](*)map[string]interface{} +*Tree (*)struct, (*)map[string]interface{} +[]*Tree (*)[](*)struct, (*)[](*)map[string]interface{} []interface{} (as interface{}) (*)[]primitive, (*)[]([]interface{}) interface{} (*)primitive -TomlTree primitive types and corresponding marshal types +Tree primitive types and corresponding marshal types ----------------------------------------------------------- uint64 uint, uint8-uint64, pointers to same int64 int, int8-uint64, pointers to same @@ -36,7 +36,7 @@ type tomlOpts struct { var timeType = reflect.TypeOf(time.Time{}) var marshalerType = reflect.TypeOf(new(Marshaler)).Elem() -// Check if the given marshall type maps to a TomlTree primitive +// Check if the given marshall type maps to a Tree primitive func isPrimitive(mtype reflect.Type) bool { switch mtype.Kind() { case reflect.Ptr: @@ -58,7 +58,7 @@ func isPrimitive(mtype reflect.Type) bool { } } -// Check if the given marshall type maps to a TomlTree slice +// Check if the given marshall type maps to a Tree slice func isTreeSlice(mtype reflect.Type) bool { switch mtype.Kind() { case reflect.Slice: @@ -68,7 +68,7 @@ func isTreeSlice(mtype reflect.Type) bool { } } -// Check if the given marshall type maps to a non-TomlTree slice +// Check if the given marshall type maps to a non-Tree slice func isOtherSlice(mtype reflect.Type) bool { switch mtype.Kind() { case reflect.Ptr: @@ -80,7 +80,7 @@ func isOtherSlice(mtype reflect.Type) bool { } } -// Check if the given marshall type maps to a TomlTree +// Check if the given marshall type maps to a Tree func isTree(mtype reflect.Type) bool { switch mtype.Kind() { case reflect.Map: @@ -134,11 +134,11 @@ func Marshal(v interface{}) ([]byte, error) { } // Convert given marshal struct or map value to toml tree -func valueToTree(mtype reflect.Type, mval reflect.Value) (*TomlTree, error) { +func valueToTree(mtype reflect.Type, mval reflect.Value) (*Tree, error) { if mtype.Kind() == reflect.Ptr { return valueToTree(mtype.Elem(), mval.Elem()) } - tval := newTomlTree() + tval := newTree() switch mtype.Kind() { case reflect.Struct: for i := 0; i < mtype.NumField(); i++ { @@ -166,8 +166,8 @@ func valueToTree(mtype reflect.Type, mval reflect.Value) (*TomlTree, error) { } // Convert given marshal slice to slice of Toml trees -func valueToTreeSlice(mtype reflect.Type, mval reflect.Value) ([]*TomlTree, error) { - tval := make([]*TomlTree, mval.Len(), mval.Len()) +func valueToTreeSlice(mtype reflect.Type, mval reflect.Value) ([]*Tree, error) { + tval := make([]*Tree, mval.Len(), mval.Len()) for i := 0; i < mval.Len(); i++ { val, err := valueToTree(mtype.Elem(), mval.Index(i)) if err != nil { @@ -225,10 +225,10 @@ func valueToToml(mtype reflect.Type, mval reflect.Value) (interface{}, error) { } } -// Unmarshal attempts to unmarshal the TomlTree into a Go struct pointed by v. +// Unmarshal attempts to unmarshal the Tree into a Go struct pointed by v. // Neither Unmarshaler interfaces nor UnmarshalTOML functions are supported for // sub-structs, and only definite types can be unmarshaled. -func (t *TomlTree) Unmarshal(v interface{}) error { +func (t *Tree) Unmarshal(v interface{}) error { mtype := reflect.TypeOf(v) if mtype.Kind() != reflect.Ptr || mtype.Elem().Kind() != reflect.Struct { return errors.New("Only a pointer to struct can be unmarshaled from TOML") @@ -256,7 +256,7 @@ func Unmarshal(data []byte, v interface{}) error { } // Convert toml tree to marshal struct or map, using marshal type -func valueFromTree(mtype reflect.Type, tval *TomlTree) (reflect.Value, error) { +func valueFromTree(mtype reflect.Type, tval *Tree) (reflect.Value, error) { if mtype.Kind() == reflect.Ptr { return unwrapPointer(mtype, tval) } @@ -295,7 +295,7 @@ func valueFromTree(mtype reflect.Type, tval *TomlTree) (reflect.Value, error) { } // Convert toml value to marshal struct/map slice, using marshal type -func valueFromTreeSlice(mtype reflect.Type, tval []*TomlTree) (reflect.Value, error) { +func valueFromTreeSlice(mtype reflect.Type, tval []*Tree) (reflect.Value, error) { mval := reflect.MakeSlice(mtype, len(tval), len(tval)) for i := 0; i < len(tval); i++ { val, err := valueFromTree(mtype.Elem(), tval[i]) @@ -327,9 +327,9 @@ func valueFromToml(mtype reflect.Type, tval interface{}) (reflect.Value, error) } switch { case isTree(mtype): - return valueFromTree(mtype, tval.(*TomlTree)) + return valueFromTree(mtype, tval.(*Tree)) case isTreeSlice(mtype): - return valueFromTreeSlice(mtype, tval.([]*TomlTree)) + return valueFromTreeSlice(mtype, tval.([]*Tree)) case isOtherSlice(mtype): return valueFromOtherSlice(mtype, tval.([]interface{})) default: diff --git a/marshal_test.go b/marshal_test.go index aef4d7f..dbfc7c1 100644 --- a/marshal_test.go +++ b/marshal_test.go @@ -181,7 +181,7 @@ func TestDocPartialUnmarshal(t *testing.T) { result := testDocSubs{} tree, _ := LoadFile("marshal_test.toml") - subTree := tree.Get("subdoc").(*TomlTree) + subTree := tree.Get("subdoc").(*Tree) err := subTree.Unmarshal(&result) expected := docData.Subdocs if err != nil { diff --git a/parser.go b/parser.go index 20e90a3..64eb0e5 100644 --- a/parser.go +++ b/parser.go @@ -14,7 +14,7 @@ import ( type tomlParser struct { flow chan token - tree *TomlTree + tree *Tree tokensBuffer []token currentTable []string seenTableKeys []string @@ -106,18 +106,18 @@ func (p *tomlParser) parseGroupArray() tomlParserStateFn { } p.tree.createSubTree(keys[:len(keys)-1], startToken.Position) // create parent entries destTree := p.tree.GetPath(keys) - var array []*TomlTree + var array []*Tree if destTree == nil { - array = make([]*TomlTree, 0) - } else if target, ok := destTree.([]*TomlTree); ok && target != nil { - array = destTree.([]*TomlTree) + array = make([]*Tree, 0) + } else if target, ok := destTree.([]*Tree); ok && target != nil { + array = destTree.([]*Tree) } else { p.raiseError(key, "key %s is already assigned and not of type table array", key) } p.currentTable = keys // add a new tree to the end of the table array - newTree := newTomlTree() + newTree := newTree() newTree.position = startToken.Position array = append(array, newTree) p.tree.SetPath(p.currentTable, array) @@ -183,11 +183,11 @@ func (p *tomlParser) parseAssign() tomlParserStateFn { } // find the table to assign, looking out for arrays of tables - var targetNode *TomlTree + var targetNode *Tree switch node := p.tree.GetPath(tableKey).(type) { - case []*TomlTree: + case []*Tree: targetNode = node[len(node)-1] - case *TomlTree: + case *Tree: targetNode = node default: p.raiseError(key, "Unknown table type for path: %s", @@ -212,7 +212,7 @@ func (p *tomlParser) parseAssign() tomlParserStateFn { var toInsert interface{} switch value.(type) { - case *TomlTree, []*TomlTree: + case *Tree, []*Tree: toInsert = value default: toInsert = &tomlValue{value, key.Position} @@ -289,8 +289,8 @@ func tokenIsComma(t *token) bool { return t != nil && t.typ == tokenComma } -func (p *tomlParser) parseInlineTable() *TomlTree { - tree := newTomlTree() +func (p *tomlParser) parseInlineTable() *Tree { + tree := newTree() var previous *token Loop: for { @@ -360,22 +360,22 @@ func (p *tomlParser) parseArray() interface{} { p.getToken() } } - // An array of TomlTrees is actually an array of inline + // An array of Trees is actually an array of inline // tables, which is a shorthand for a table array. If the - // array was not converted from []interface{} to []*TomlTree, + // array was not converted from []interface{} to []*Tree, // the two notations would not be equivalent. - if arrayType == reflect.TypeOf(newTomlTree()) { - tomlArray := make([]*TomlTree, len(array)) + if arrayType == reflect.TypeOf(newTree()) { + tomlArray := make([]*Tree, len(array)) for i, v := range array { - tomlArray[i] = v.(*TomlTree) + tomlArray[i] = v.(*Tree) } return tomlArray } return array } -func parseToml(flow chan token) *TomlTree { - result := newTomlTree() +func parseToml(flow chan token) *Tree { + result := newTree() result.position = Position{1, 1} parser := &tomlParser{ flow: flow, diff --git a/parser_test.go b/parser_test.go index 58aae20..508cb65 100644 --- a/parser_test.go +++ b/parser_test.go @@ -9,7 +9,7 @@ import ( "github.com/davecgh/go-spew/spew" ) -func assertSubTree(t *testing.T, path []string, tree *TomlTree, err error, ref map[string]interface{}) { +func assertSubTree(t *testing.T, path []string, tree *Tree, err error, ref map[string]interface{}) { if err != nil { t.Error("Non-nil error:", err.Error()) return @@ -20,12 +20,12 @@ func assertSubTree(t *testing.T, path []string, tree *TomlTree, err error, ref m // NOTE: directly access key instead of resolve by path // NOTE: see TestSpecialKV switch node := tree.GetPath([]string{k}).(type) { - case []*TomlTree: + case []*Tree: t.Log("\tcomparing key", nextPath, "by array iteration") for idx, item := range node { assertSubTree(t, nextPath, item, err, v.([]map[string]interface{})[idx]) } - case *TomlTree: + case *Tree: t.Log("\tcomparing key", nextPath, "by subtree assestion") assertSubTree(t, nextPath, node, err, v.(map[string]interface{})) default: @@ -37,14 +37,14 @@ func assertSubTree(t *testing.T, path []string, tree *TomlTree, err error, ref m } } -func assertTree(t *testing.T, tree *TomlTree, err error, ref map[string]interface{}) { +func assertTree(t *testing.T, tree *Tree, err error, ref map[string]interface{}) { t.Log("Asserting tree:\n", spew.Sdump(tree)) assertSubTree(t, []string{}, tree, err, ref) t.Log("Finished tree assertion.") } func TestCreateSubTree(t *testing.T) { - tree := newTomlTree() + tree := newTree() tree.createSubTree([]string{"a", "b", "c"}, Position{}) tree.Set("a.b.c", 42) if tree.Get("a.b.c") != 42 { diff --git a/query/doc.go b/query/doc.go index fa2e457..f999fc9 100644 --- a/query/doc.go +++ b/query/doc.go @@ -112,7 +112,7 @@ // There are several filters provided with the library: // // tree -// Allows nodes of type TomlTree. +// Allows nodes of type Tree. // int // Allows nodes of type int64. // float @@ -138,7 +138,7 @@ // // Compiled Queries // -// Queries may be executed directly on a TomlTree object, or compiled ahead +// Queries may be executed directly on a Tree object, or compiled ahead // of time and executed discretely. The former is more convienent, but has the // penalty of having to recompile the query expression each time. // @@ -163,7 +163,7 @@ // // // define the filter, and assign it to the query // query.SetFilter("bazOnly", func(node interface{}) bool{ -// if tree, ok := node.(*TomlTree); ok { +// if tree, ok := node.(*Tree); ok { // return tree.Has("baz") // } // return false // reject all other node types diff --git a/query/match.go b/query/match.go index 1aac035..d7bb15a 100644 --- a/query/match.go +++ b/query/match.go @@ -42,7 +42,7 @@ func newMatchKeyFn(name string) *matchKeyFn { } func (f *matchKeyFn) call(node interface{}, ctx *queryContext) { - if array, ok := node.([]*toml.TomlTree); ok { + if array, ok := node.([]*toml.Tree); ok { for _, tree := range array { item := tree.Get(f.Name) if item != nil { @@ -50,7 +50,7 @@ func (f *matchKeyFn) call(node interface{}, ctx *queryContext) { f.next.call(item, ctx) } } - } else if tree, ok := node.(*toml.TomlTree); ok { + } else if tree, ok := node.(*toml.Tree); ok { item := tree.Get(f.Name) if item != nil { ctx.lastPosition = tree.GetPosition(f.Name) @@ -72,7 +72,7 @@ func newMatchIndexFn(idx int) *matchIndexFn { func (f *matchIndexFn) call(node interface{}, ctx *queryContext) { if arr, ok := node.([]interface{}); ok { if f.Idx < len(arr) && f.Idx >= 0 { - if treesArray, ok := node.([]*toml.TomlTree); ok { + if treesArray, ok := node.([]*toml.Tree); ok { if len(treesArray) > 0 { ctx.lastPosition = treesArray[0].Position() } @@ -107,7 +107,7 @@ func (f *matchSliceFn) call(node interface{}, ctx *queryContext) { } // loop and gather for idx := realStart; idx < realEnd; idx += f.Step { - if treesArray, ok := node.([]*toml.TomlTree); ok { + if treesArray, ok := node.([]*toml.Tree); ok { if len(treesArray) > 0 { ctx.lastPosition = treesArray[0].Position() } @@ -127,7 +127,7 @@ func newMatchAnyFn() *matchAnyFn { } func (f *matchAnyFn) call(node interface{}, ctx *queryContext) { - if tree, ok := node.(*toml.TomlTree); ok { + if tree, ok := node.(*toml.Tree); ok { for _, k := range tree.Keys() { v := tree.Get(k) ctx.lastPosition = tree.GetPosition(k) @@ -164,17 +164,17 @@ func newMatchRecursiveFn() *matchRecursiveFn { func (f *matchRecursiveFn) call(node interface{}, ctx *queryContext) { originalPosition := ctx.lastPosition - if tree, ok := node.(*toml.TomlTree); ok { - var visit func(tree *toml.TomlTree) - visit = func(tree *toml.TomlTree) { + if tree, ok := node.(*toml.Tree); ok { + var visit func(tree *toml.Tree) + visit = func(tree *toml.Tree) { for _, k := range tree.Keys() { v := tree.Get(k) ctx.lastPosition = tree.GetPosition(k) f.next.call(v, ctx) switch node := v.(type) { - case *toml.TomlTree: + case *toml.Tree: visit(node) - case []*toml.TomlTree: + case []*toml.Tree: for _, subtree := range node { visit(subtree) } @@ -205,7 +205,7 @@ func (f *matchFilterFn) call(node interface{}, ctx *queryContext) { f.Pos.String(), f.Name)) } switch castNode := node.(type) { - case *toml.TomlTree: + case *toml.Tree: for _, k := range castNode.Keys() { v := castNode.Get(k) if fn(v) { @@ -213,7 +213,7 @@ func (f *matchFilterFn) call(node interface{}, ctx *queryContext) { f.next.call(v, ctx) } } - case []*toml.TomlTree: + case []*toml.Tree: for _, v := range castNode { if fn(v) { if len(castNode) > 0 { diff --git a/query/parser_test.go b/query/parser_test.go index 5057853..b1d0a3e 100644 --- a/query/parser_test.go +++ b/query/parser_test.go @@ -36,7 +36,7 @@ func valueString(root interface{}) string { } sort.Strings(items) result = "[" + strings.Join(items, ", ") + "]" - case *toml.TomlTree: + case *toml.Tree: // workaround for unreliable map key ordering items := []string{} for _, k := range node.Keys() { diff --git a/query/query.go b/query/query.go index 2f4de78..1c6cd80 100644 --- a/query/query.go +++ b/query/query.go @@ -53,7 +53,7 @@ type queryContext struct { type pathFn interface { setNext(next pathFn) // it is the caller's responsibility to set the ctx.lastPosition before invoking call() - // node can be one of: *toml.TomlTree, []*toml.TomlTree, or a scalar + // node can be one of: *toml.Tree, []*toml.Tree, or a scalar call(node interface{}, ctx *queryContext) } @@ -84,13 +84,13 @@ func (q *Query) appendPath(next pathFn) { } // Compile compiles a TOML path expression. The returned Query can be used -// to match elements within a TomlTree and its descendants. See Execute. +// to match elements within a Tree and its descendants. See Execute. func Compile(path string) (*Query, error) { return parseQuery(lexQuery(path)) } -// Execute executes a query against a TomlTree, and returns the result of the query. -func (q *Query) Execute(tree *toml.TomlTree) *Result { +// Execute executes a query against a Tree, and returns the result of the query. +func (q *Query) Execute(tree *toml.Tree) *Result { result := &Result{ items: []interface{}{}, positions: []toml.Position{}, @@ -109,7 +109,7 @@ func (q *Query) Execute(tree *toml.TomlTree) *Result { } // CompileAndExecute is a shorthand for Compile(path) followed by Execute(tree). -func CompileAndExecute(path string, tree *toml.TomlTree) (*Result, error) { +func CompileAndExecute(path string, tree *toml.Tree) (*Result, error) { query, err := Compile(path) if err != nil { return nil, err @@ -132,7 +132,7 @@ func (q *Query) SetFilter(name string, fn NodeFilterFn) { var defaultFilterFunctions = map[string]NodeFilterFn{ "tree": func(node interface{}) bool { - _, ok := node.(*toml.TomlTree) + _, ok := node.(*toml.Tree) return ok }, "int": func(node interface{}) bool { diff --git a/query/query_test.go b/query/query_test.go index 4433f5f..903a8dc 100644 --- a/query/query_test.go +++ b/query/query_test.go @@ -99,13 +99,13 @@ func ExampleNodeFilterFn_filterExample() { // define the filter, and assign it to the query query.SetFilter("bazOnly", func(node interface{}) bool { - if tree, ok := node.(*toml.TomlTree); ok { + if tree, ok := node.(*toml.Tree); ok { return tree.Has("baz") } return false // reject all other node types }) - // results contain only the 'struct_two' TomlTree + // results contain only the 'struct_two' Tree query.Execute(tree) } @@ -147,8 +147,8 @@ func TestTomlQuery(t *testing.T) { t.Errorf("Expected resultset of 1, got %d instead: %v", len(values), values) } - if tt, ok := values[0].(*toml.TomlTree); !ok { - t.Errorf("Expected type of TomlTree: %T", values[0]) + if tt, ok := values[0].(*toml.Tree); !ok { + t.Errorf("Expected type of Tree: %T", values[0]) } else if tt.Get("a") != int64(1) { t.Errorf("Expected 'a' with a value 1: %v", tt.Get("a")) } else if tt.Get("b") != int64(2) { diff --git a/toml.go b/toml.go index d07c1b4..9966321 100644 --- a/toml.go +++ b/toml.go @@ -14,35 +14,35 @@ type tomlValue struct { position Position } -// TomlTree is the result of the parsing of a TOML file. -type TomlTree struct { - values map[string]interface{} // string -> *tomlValue, *TomlTree, []*TomlTree +// Tree is the result of the parsing of a TOML file. +type Tree struct { + values map[string]interface{} // string -> *tomlValue, *Tree, []*Tree position Position } -func newTomlTree() *TomlTree { - return &TomlTree{ +func newTree() *Tree { + return &Tree{ values: make(map[string]interface{}), position: Position{}, } } -// TreeFromMap initializes a new TomlTree object using the given map. -func TreeFromMap(m map[string]interface{}) (*TomlTree, error) { +// TreeFromMap initializes a new Tree object using the given map. +func TreeFromMap(m map[string]interface{}) (*Tree, error) { result, err := toTree(m) if err != nil { return nil, err } - return result.(*TomlTree), nil + return result.(*Tree), nil } // Position returns the position of the tree. -func (t *TomlTree) Position() Position { +func (t *Tree) Position() Position { return t.position } // Has returns a boolean indicating if the given key exists. -func (t *TomlTree) Has(key string) bool { +func (t *Tree) Has(key string) bool { if key == "" { return false } @@ -50,13 +50,13 @@ func (t *TomlTree) Has(key string) bool { } // HasPath returns true if the given path of keys exists, false otherwise. -func (t *TomlTree) HasPath(keys []string) bool { +func (t *Tree) HasPath(keys []string) bool { return t.GetPath(keys) != nil } // Keys returns the keys of the toplevel tree. // Warning: this is a costly operation. -func (t *TomlTree) Keys() []string { +func (t *Tree) Keys() []string { keys := make([]string, len(t.values)) i := 0 for k := range t.values { @@ -66,11 +66,11 @@ func (t *TomlTree) Keys() []string { return keys } -// Get the value at key in the TomlTree. +// Get the value at key in the Tree. // Key is a dot-separated path (e.g. a.b.c). // Returns nil if the path does not exist in the tree. // If keys is of length zero, the current tree is returned. -func (t *TomlTree) Get(key string) interface{} { +func (t *Tree) Get(key string) interface{} { if key == "" { return t } @@ -83,7 +83,7 @@ func (t *TomlTree) Get(key string) interface{} { // GetPath returns the element in the tree indicated by 'keys'. // If keys is of length zero, the current tree is returned. -func (t *TomlTree) GetPath(keys []string) interface{} { +func (t *Tree) GetPath(keys []string) interface{} { if len(keys) == 0 { return t } @@ -94,9 +94,9 @@ func (t *TomlTree) GetPath(keys []string) interface{} { return nil } switch node := value.(type) { - case *TomlTree: + case *Tree: subtree = node - case []*TomlTree: + case []*Tree: // go to most recent element if len(node) == 0 { return nil @@ -116,7 +116,7 @@ func (t *TomlTree) GetPath(keys []string) interface{} { } // GetPosition returns the position of the given key. -func (t *TomlTree) GetPosition(key string) Position { +func (t *Tree) GetPosition(key string) Position { if key == "" { return t.position } @@ -125,7 +125,7 @@ func (t *TomlTree) GetPosition(key string) Position { // GetPositionPath returns the element in the tree indicated by 'keys'. // If keys is of length zero, the current tree is returned. -func (t *TomlTree) GetPositionPath(keys []string) Position { +func (t *Tree) GetPositionPath(keys []string) Position { if len(keys) == 0 { return t.position } @@ -136,9 +136,9 @@ func (t *TomlTree) GetPositionPath(keys []string) Position { return Position{0, 0} } switch node := value.(type) { - case *TomlTree: + case *Tree: subtree = node - case []*TomlTree: + case []*Tree: // go to most recent element if len(node) == 0 { return Position{0, 0} @@ -152,9 +152,9 @@ func (t *TomlTree) GetPositionPath(keys []string) Position { switch node := subtree.values[keys[len(keys)-1]].(type) { case *tomlValue: return node.position - case *TomlTree: + case *Tree: return node.position - case []*TomlTree: + case []*Tree: // go to most recent element if len(node) == 0 { return Position{0, 0} @@ -166,7 +166,7 @@ func (t *TomlTree) GetPositionPath(keys []string) Position { } // GetDefault works like Get but with a default value -func (t *TomlTree) GetDefault(key string, def interface{}) interface{} { +func (t *Tree) GetDefault(key string, def interface{}) interface{} { val := t.Get(key) if val == nil { return def @@ -177,29 +177,29 @@ func (t *TomlTree) GetDefault(key string, def interface{}) interface{} { // Set an element in the tree. // Key is a dot-separated path (e.g. a.b.c). // Creates all necessary intermediate trees, if needed. -func (t *TomlTree) Set(key string, value interface{}) { +func (t *Tree) Set(key string, value interface{}) { t.SetPath(strings.Split(key, "."), value) } // SetPath sets an element in the tree. // Keys is an array of path elements (e.g. {"a","b","c"}). // Creates all necessary intermediate trees, if needed. -func (t *TomlTree) SetPath(keys []string, value interface{}) { +func (t *Tree) SetPath(keys []string, value interface{}) { subtree := t for _, intermediateKey := range keys[:len(keys)-1] { nextTree, exists := subtree.values[intermediateKey] if !exists { - nextTree = newTomlTree() + nextTree = newTree() subtree.values[intermediateKey] = nextTree // add new element here } switch node := nextTree.(type) { - case *TomlTree: + case *Tree: subtree = node - case []*TomlTree: + case []*Tree: // go to most recent element if len(node) == 0 { // create element if it does not exist - subtree.values[intermediateKey] = append(node, newTomlTree()) + subtree.values[intermediateKey] = append(node, newTree()) } subtree = node[len(node)-1] } @@ -208,9 +208,9 @@ func (t *TomlTree) SetPath(keys []string, value interface{}) { var toInsert interface{} switch value.(type) { - case *TomlTree: + case *Tree: toInsert = value - case []*TomlTree: + case []*Tree: toInsert = value case *tomlValue: toInsert = value @@ -228,21 +228,21 @@ func (t *TomlTree) SetPath(keys []string, value interface{}) { // and tree[a][b][c] // // Returns nil on success, error object on failure -func (t *TomlTree) createSubTree(keys []string, pos Position) error { +func (t *Tree) createSubTree(keys []string, pos Position) error { subtree := t for _, intermediateKey := range keys { nextTree, exists := subtree.values[intermediateKey] if !exists { - tree := newTomlTree() + tree := newTree() tree.position = pos subtree.values[intermediateKey] = tree nextTree = tree } switch node := nextTree.(type) { - case []*TomlTree: + case []*Tree: subtree = node[len(node)-1] - case *TomlTree: + case *Tree: subtree = node default: return fmt.Errorf("unknown type for path %s (%s): %T (%#v)", @@ -252,8 +252,8 @@ func (t *TomlTree) createSubTree(keys []string, pos Position) error { return nil } -// LoadReader creates a TomlTree from any io.Reader. -func LoadReader(reader io.Reader) (tree *TomlTree, err error) { +// LoadReader creates a Tree from any io.Reader. +func LoadReader(reader io.Reader) (tree *Tree, err error) { defer func() { if r := recover(); r != nil { if _, ok := r.(runtime.Error); ok { @@ -266,13 +266,13 @@ func LoadReader(reader io.Reader) (tree *TomlTree, err error) { return } -// Load creates a TomlTree from a string. -func Load(content string) (tree *TomlTree, err error) { +// Load creates a Tree from a string. +func Load(content string) (tree *Tree, err error) { return LoadReader(strings.NewReader(content)) } -// LoadFile creates a TomlTree from a file. -func LoadFile(path string) (tree *TomlTree, err error) { +// LoadFile creates a Tree from a file. +func LoadFile(path string) (tree *Tree, err error) { file, err := os.Open(path) if err != nil { return nil, err diff --git a/toml_test.go b/toml_test.go index 871063a..ab9c242 100644 --- a/toml_test.go +++ b/toml_test.go @@ -70,12 +70,12 @@ func TestTomlHasPath(t *testing.T) { } func TestTomlGetPath(t *testing.T) { - node := newTomlTree() + node := newTree() //TODO: set other node data for idx, item := range []struct { Path []string - Expected *TomlTree + Expected *Tree }{ { // empty path test []string{}, diff --git a/tomltree_create.go b/tomltree_create.go index c6054f3..ee7114e 100644 --- a/tomltree_create.go +++ b/tomltree_create.go @@ -51,7 +51,7 @@ func simpleValueCoercion(object interface{}) (interface{}, error) { case fmt.Stringer: return original.String(), nil default: - return nil, fmt.Errorf("cannot convert type %T to TomlTree", object) + return nil, fmt.Errorf("cannot convert type %T to Tree", object) } } @@ -59,7 +59,7 @@ func sliceToTree(object interface{}) (interface{}, error) { // arrays are a bit tricky, since they can represent either a // collection of simple values, which is represented by one // *tomlValue, or an array of tables, which is represented by an - // array of *TomlTree. + // array of *Tree. // holding the assumption that this function is called from toTree only when value.Kind() is Array or Slice value := reflect.ValueOf(object) @@ -70,14 +70,14 @@ func sliceToTree(object interface{}) (interface{}, error) { } if insideType.Kind() == reflect.Map { // this is considered as an array of tables - tablesArray := make([]*TomlTree, 0, length) + tablesArray := make([]*Tree, 0, length) for i := 0; i < length; i++ { table := value.Index(i) tree, err := toTree(table.Interface()) if err != nil { return nil, err } - tablesArray = append(tablesArray, tree.(*TomlTree)) + tablesArray = append(tablesArray, tree.(*Tree)) } return tablesArray, nil } @@ -120,7 +120,7 @@ func toTree(object interface{}) (interface{}, error) { } values[key.String()] = newValue } - return &TomlTree{values, Position{}}, nil + return &Tree{values, Position{}}, nil } if value.Kind() == reflect.Array || value.Kind() == reflect.Slice { diff --git a/tomltree_create_test.go b/tomltree_create_test.go index 6c14968..1ca108a 100644 --- a/tomltree_create_test.go +++ b/tomltree_create_test.go @@ -1,9 +1,9 @@ package toml import ( + "strconv" "testing" "time" - "strconv" ) type customString string @@ -16,11 +16,11 @@ func (s stringer) String() string { func validate(t *testing.T, path string, object interface{}) { switch o := object.(type) { - case *TomlTree: + case *Tree: for key, tree := range o.values { validate(t, path+"."+key, tree) } - case []*TomlTree: + case []*Tree: for index, tree := range o { validate(t, path+"."+strconv.Itoa(index), tree) } @@ -37,11 +37,11 @@ func validate(t *testing.T, path string, object interface{}) { t.Logf("validation ok %s as %T", path, object) } -func validateTree(t *testing.T, tree *TomlTree) { +func validateTree(t *testing.T, tree *Tree) { validate(t, "", tree) } -func TestTomlTreeCreateToTree(t *testing.T) { +func TestTreeCreateToTree(t *testing.T) { data := map[string]interface{}{ "a_string": "bar", "an_int": 42, @@ -72,15 +72,15 @@ func TestTomlTreeCreateToTree(t *testing.T) { validateTree(t, tree) } -func TestTomlTreeCreateToTreeInvalidLeafType(t *testing.T) { +func TestTreeCreateToTreeInvalidLeafType(t *testing.T) { _, err := TreeFromMap(map[string]interface{}{"foo": t}) - expected := "cannot convert type *testing.T to TomlTree" + expected := "cannot convert type *testing.T to Tree" if err.Error() != expected { t.Fatalf("expected error %s, got %s", expected, err.Error()) } } -func TestTomlTreeCreateToTreeInvalidMapKeyType(t *testing.T) { +func TestTreeCreateToTreeInvalidMapKeyType(t *testing.T) { _, err := TreeFromMap(map[string]interface{}{"foo": map[int]interface{}{2: 1}}) expected := "map key needs to be a string, not int (int)" if err.Error() != expected { @@ -88,17 +88,17 @@ func TestTomlTreeCreateToTreeInvalidMapKeyType(t *testing.T) { } } -func TestTomlTreeCreateToTreeInvalidArrayMemberType(t *testing.T) { +func TestTreeCreateToTreeInvalidArrayMemberType(t *testing.T) { _, err := TreeFromMap(map[string]interface{}{"foo": []*testing.T{t}}) - expected := "cannot convert type *testing.T to TomlTree" + expected := "cannot convert type *testing.T to Tree" if err.Error() != expected { t.Fatalf("expected error %s, got %s", expected, err.Error()) } } -func TestTomlTreeCreateToTreeInvalidTableGroupType(t *testing.T) { +func TestTreeCreateToTreeInvalidTableGroupType(t *testing.T) { _, err := TreeFromMap(map[string]interface{}{"foo": []map[string]interface{}{map[string]interface{}{"hello": t}}}) - expected := "cannot convert type *testing.T to TomlTree" + expected := "cannot convert type *testing.T to Tree" if err.Error() != expected { t.Fatalf("expected error %s, got %s", expected, err.Error()) } diff --git a/tomltree_write.go b/tomltree_write.go index 6a7fa17..7358144 100644 --- a/tomltree_write.go +++ b/tomltree_write.go @@ -4,11 +4,11 @@ import ( "bytes" "fmt" "io" + "reflect" "sort" "strconv" "strings" "time" - "reflect" ) // encodes a string to a TOML-compliant string value @@ -83,14 +83,14 @@ func tomlValueStringRepresentation(v interface{}) (string, error) { return "", fmt.Errorf("unsupported value type %T: %v", v, v) } -func (t *TomlTree) writeTo(w io.Writer, indent, keyspace string, bytesCount int64) (int64, error) { +func (t *Tree) writeTo(w io.Writer, indent, keyspace string, bytesCount int64) (int64, error) { simpleValuesKeys := make([]string, 0) complexValuesKeys := make([]string, 0) for k := range t.values { v := t.values[k] switch v.(type) { - case *TomlTree, []*TomlTree: + case *Tree, []*Tree: complexValuesKeys = append(complexValuesKeys, k) default: simpleValuesKeys = append(simpleValuesKeys, k) @@ -129,7 +129,7 @@ func (t *TomlTree) writeTo(w io.Writer, indent, keyspace string, bytesCount int6 switch node := v.(type) { // node has to be of those two types given how keys are sorted above - case *TomlTree: + case *Tree: tableName := fmt.Sprintf("\n%s[%s]\n", indent, combinedKey) writtenBytesCount, err := w.Write([]byte(tableName)) bytesCount += int64(writtenBytesCount) @@ -140,7 +140,7 @@ func (t *TomlTree) writeTo(w io.Writer, indent, keyspace string, bytesCount int6 if err != nil { return bytesCount, err } - case []*TomlTree: + case []*Tree: for _, subTree := range node { if len(subTree.values) > 0 { tableArrayName := fmt.Sprintf("\n%s[[%s]]\n", indent, combinedKey) @@ -162,16 +162,16 @@ func (t *TomlTree) writeTo(w io.Writer, indent, keyspace string, bytesCount int6 return bytesCount, nil } -// WriteTo encode the TomlTree as Toml and writes it to the writer w. +// WriteTo encode the Tree as Toml and writes it to the writer w. // Returns the number of bytes written in case of success, or an error if anything happened. -func (t *TomlTree) WriteTo(w io.Writer) (int64, error) { +func (t *Tree) WriteTo(w io.Writer) (int64, error) { return t.writeTo(w, "", "", 0) } // ToTomlString generates a human-readable representation of the current tree. // Output spans multiple lines, and is suitable for ingest by a TOML parser. // If the conversion cannot be performed, ToString returns a non-nil error. -func (t *TomlTree) ToTomlString() (string, error) { +func (t *Tree) ToTomlString() (string, error) { var buf bytes.Buffer _, err := t.WriteTo(&buf) if err != nil { @@ -182,7 +182,7 @@ func (t *TomlTree) ToTomlString() (string, error) { // String generates a human-readable representation of the current tree. // Alias of ToString. Present to implement the fmt.Stringer interface. -func (t *TomlTree) String() string { +func (t *Tree) String() string { result, _ := t.ToTomlString() return result } @@ -196,18 +196,18 @@ func (t *TomlTree) String() string { // * time.Time // * map[string]interface{} (where interface{} is any of this list) // * []interface{} (where interface{} is any of this list) -func (t *TomlTree) ToMap() map[string]interface{} { +func (t *Tree) ToMap() map[string]interface{} { result := map[string]interface{}{} for k, v := range t.values { switch node := v.(type) { - case []*TomlTree: + case []*Tree: var array []interface{} for _, item := range node { array = append(array, item.ToMap()) } result[k] = array - case *TomlTree: + case *Tree: result[k] = node.ToMap() case *tomlValue: result[k] = node.value diff --git a/tomltree_write_test.go b/tomltree_write_test.go index b5ad8db..1a006da 100644 --- a/tomltree_write_test.go +++ b/tomltree_write_test.go @@ -40,7 +40,7 @@ func assertErrorString(t *testing.T, expected string, err error) { } } -func TestTomlTreeWriteToTomlString(t *testing.T) { +func TestTreeWriteToTomlString(t *testing.T) { toml, err := Load(`name = { first = "Tom", last = "Preston-Werner" } points = { x = 1, y = 2 }`) @@ -63,7 +63,7 @@ points = { x = 1, y = 2 }`) }) } -func TestTomlTreeWriteToTomlStringSimple(t *testing.T) { +func TestTreeWriteToTomlStringSimple(t *testing.T) { tree, err := Load("[foo]\n\n[[foo.bar]]\na = 42\n\n[[foo.bar]]\na = 69\n") if err != nil { t.Errorf("Test failed to parse: %v", err) @@ -79,7 +79,7 @@ func TestTomlTreeWriteToTomlStringSimple(t *testing.T) { } } -func TestTomlTreeWriteToTomlStringKeysOrders(t *testing.T) { +func TestTreeWriteToTomlStringKeysOrders(t *testing.T) { for i := 0; i < 100; i++ { tree, _ := Load(` foobar = true @@ -119,7 +119,7 @@ func testMaps(t *testing.T, actual, expected map[string]interface{}) { } } -func TestTomlTreeWriteToMapSimple(t *testing.T) { +func TestTreeWriteToMapSimple(t *testing.T) { tree, _ := Load("a = 42\nb = 17") expected := map[string]interface{}{ @@ -130,32 +130,32 @@ func TestTomlTreeWriteToMapSimple(t *testing.T) { testMaps(t, tree.ToMap(), expected) } -func TestTomlTreeWriteToInvalidTreeSimpleValue(t *testing.T) { - tree := TomlTree{values: map[string]interface{}{"foo": int8(1)}} +func TestTreeWriteToInvalidTreeSimpleValue(t *testing.T) { + tree := Tree{values: map[string]interface{}{"foo": int8(1)}} _, err := tree.ToTomlString() assertErrorString(t, "invalid value type at foo: int8", err) } -func TestTomlTreeWriteToInvalidTreeTomlValue(t *testing.T) { - tree := TomlTree{values: map[string]interface{}{"foo": &tomlValue{int8(1), Position{}}}} +func TestTreeWriteToInvalidTreeTomlValue(t *testing.T) { + tree := Tree{values: map[string]interface{}{"foo": &tomlValue{int8(1), Position{}}}} _, err := tree.ToTomlString() assertErrorString(t, "unsupported value type int8: 1", err) } -func TestTomlTreeWriteToInvalidTreeTomlValueArray(t *testing.T) { - tree := TomlTree{values: map[string]interface{}{"foo": &tomlValue{[]interface{}{int8(1)}, Position{}}}} +func TestTreeWriteToInvalidTreeTomlValueArray(t *testing.T) { + tree := Tree{values: map[string]interface{}{"foo": &tomlValue{[]interface{}{int8(1)}, Position{}}}} _, err := tree.ToTomlString() assertErrorString(t, "unsupported value type int8: 1", err) } -func TestTomlTreeWriteToFailingWriterInSimpleValue(t *testing.T) { +func TestTreeWriteToFailingWriterInSimpleValue(t *testing.T) { toml, _ := Load(`a = 2`) writer := failingWriter{failAt: 0, written: 0} _, err := toml.WriteTo(writer) assertErrorString(t, "failingWriter failed after writting 0 bytes", err) } -func TestTomlTreeWriteToFailingWriterInTable(t *testing.T) { +func TestTreeWriteToFailingWriterInTable(t *testing.T) { toml, _ := Load(` [b] a = 2`) @@ -168,7 +168,7 @@ a = 2`) assertErrorString(t, "failingWriter failed after writting 13 bytes", err) } -func TestTomlTreeWriteToFailingWriterInArray(t *testing.T) { +func TestTreeWriteToFailingWriterInArray(t *testing.T) { toml, _ := Load(` [[b]] a = 2`) @@ -181,7 +181,7 @@ a = 2`) assertErrorString(t, "failingWriter failed after writting 15 bytes", err) } -func TestTomlTreeWriteToMapExampleFile(t *testing.T) { +func TestTreeWriteToMapExampleFile(t *testing.T) { tree, _ := LoadFile("example.toml") expected := map[string]interface{}{ "title": "TOML Example", @@ -217,7 +217,7 @@ func TestTomlTreeWriteToMapExampleFile(t *testing.T) { testMaps(t, tree.ToMap(), expected) } -func TestTomlTreeWriteToMapWithTablesInMultipleChunks(t *testing.T) { +func TestTreeWriteToMapWithTablesInMultipleChunks(t *testing.T) { tree, _ := Load(` [[menu.main]] a = "menu 1" @@ -238,7 +238,7 @@ func TestTomlTreeWriteToMapWithTablesInMultipleChunks(t *testing.T) { testMaps(t, treeMap, expected) } -func TestTomlTreeWriteToMapWithArrayOfInlineTables(t *testing.T) { +func TestTreeWriteToMapWithArrayOfInlineTables(t *testing.T) { tree, _ := Load(` [params] language_tabs = [