diff --git a/toml.go b/toml.go index 20180ab..41ad9b4 100644 --- a/toml.go +++ b/toml.go @@ -292,6 +292,34 @@ func (t *Tree) SetPathWithComment(keys []string, comment string, commented bool, subtree.values[keys[len(keys)-1]] = toInsert } +// Delete removes a key from the tree. +// Key is a dot-separated path (e.g. a.b.c). +func (t *Tree) Delete(key string) error { + keys, err := parseKey(key) + if err != nil { + return err + } + return t.DeletePath(keys) +} + +// Delete removes a key from the tree. +// Keys is an array of path elements (e.g. {"a","b","c"}). +func (t *Tree) DeletePath(keys []string) error { + keyLen := len(keys) + if keyLen == 1 { + delete(t.values, keys[0]) + return nil + } + tree := t.GetPath(keys[:keyLen-1]) + item := keys[keyLen-1] + switch node := tree.(type) { + case *Tree: + delete(node.values, item) + return nil + } + return errors.New("no such key to delete") +} + // createSubTree takes a tree and a key and create the necessary intermediate // subtrees to create a subtree at that point. In-place. // diff --git a/toml_test.go b/toml_test.go index 9bbe2c7..81c3954 100644 --- a/toml_test.go +++ b/toml_test.go @@ -69,6 +69,60 @@ func TestTomlHasPath(t *testing.T) { } } +func TestTomlDelete(t *testing.T) { + tree, _ := Load(` + key = "value" + `) + err := tree.Delete("key") + if err != nil { + t.Errorf("Delete - unexpected error while deleting key: %s", err.Error()) + } + + if tree.Get("key") != nil { + t.Errorf("Delete should have removed key but did not.") + } + +} + +func TestTomlDeleteUnparsableKey(t *testing.T) { + tree, _ := Load(` + key = "value" + `) + err := tree.Delete(".") + if err == nil { + t.Errorf("Delete should error") + } +} + +func TestTomlDeleteNestedKey(t *testing.T) { + tree, _ := Load(` + [foo] + [foo.bar] + key = "value" + `) + err := tree.Delete("foo.bar.key") + if err != nil { + t.Errorf("Error while deleting nested key: %s", err.Error()) + } + + if tree.Get("key") != nil { + t.Errorf("Delete should have removed nested key but did not.") + } + +} + +func TestTomlDeleteNonexistentNestedKey(t *testing.T) { + tree, _ := Load(` + [foo] + [foo.bar] + key = "value" + `) + err := tree.Delete("foo.not.there.key") + if err == nil { + t.Errorf("Delete should have thrown an error trying to delete key in nonexistent tree") + } +} + func TestTomlGetPath(t *testing.T) { node := newTree() //TODO: set other node data