diff --git a/internal/unmarshaler/parser.go b/internal/unmarshaler/parser.go index 9d127f1..a2ba7f2 100644 --- a/internal/unmarshaler/parser.go +++ b/internal/unmarshaler/parser.go @@ -209,13 +209,15 @@ func (p *parser) parseVal(b []byte) (ast.Node, []byte, error) { if !scanFollowsTrue(b) { return node, nil, fmt.Errorf("expected 'true'") } - // TODO + node.Kind = ast.Bool + node.Data = b[:4] return node, b[4:], nil case 'f': if !scanFollowsFalse(b) { return node, nil, fmt.Errorf("expected 'false'") } - // TODO + node.Kind = ast.Bool + node.Data = b[:5] return node, b[5:], nil case '[': node.Kind = ast.Array diff --git a/internal/unmarshaler/parser_test.go b/internal/unmarshaler/parser_test.go index 0f2a71c..3052d9a 100644 --- a/internal/unmarshaler/parser_test.go +++ b/internal/unmarshaler/parser_test.go @@ -33,6 +33,25 @@ func TestParser_AST(t *testing.T) { }, }, }, + { + desc: "simple bool assignment", + input: `A = true`, + ast: ast.Root{ + ast.Node{ + Kind: ast.KeyValue, + Children: []ast.Node{ + { + Kind: ast.Key, + Data: []byte(`A`), + }, + { + Kind: ast.Bool, + Data: []byte(`true`), + }, + }, + }, + }, + }, { desc: "array of strings", input: `A = ["hello", ["world", "again"]]`, diff --git a/internal/unmarshaler/targets.go b/internal/unmarshaler/targets.go index a0e2fd1..6adaed6 100644 --- a/internal/unmarshaler/targets.go +++ b/internal/unmarshaler/targets.go @@ -12,6 +12,9 @@ type target interface { // Store a string at the target. setString(v string) error + // Store a boolean at the target + setBool(v bool) error + // Creates a new value of the container's element type, and returns a // target to it. pushNew() (target, error) @@ -65,6 +68,21 @@ func (t valueTarget) setString(v string) error { return nil } +func (t valueTarget) setBool(v bool) error { + f := t.get() + + switch f.Kind() { + case reflect.Bool: + f.SetBool(v) + case reflect.Interface: + f.Set(reflect.ValueOf(v)) + default: + return fmt.Errorf("cannot assign bool to a %s", f.String()) + } + + return nil +} + func (t valueTarget) pushNew() (target, error) { f := t.get() diff --git a/internal/unmarshaler/unmarshaler.go b/internal/unmarshaler/unmarshaler.go index 2f8c2ab..6b2a665 100644 --- a/internal/unmarshaler/unmarshaler.go +++ b/internal/unmarshaler/unmarshaler.go @@ -78,6 +78,8 @@ func unmarshalValue(x target, node *ast.Node) error { switch node.Kind { case ast.String: return unmarshalString(x, node) + case ast.Bool: + return unmarshalBool(x, node) case ast.Array: return unmarshalArray(x, node) case ast.InlineTable: @@ -92,6 +94,12 @@ func unmarshalString(x target, node *ast.Node) error { return x.setString(string(node.Data)) } +func unmarshalBool(x target, node *ast.Node) error { + assertNode(ast.Bool, node) + v := node.Data[0] == 't' + return x.setBool(v) +} + func unmarshalInlineTable(x target, node *ast.Node) error { assertNode(ast.InlineTable, node) diff --git a/internal/unmarshaler/unmarshaler_test.go b/internal/unmarshaler/unmarshaler_test.go index 900514c..79030e9 100644 --- a/internal/unmarshaler/unmarshaler_test.go +++ b/internal/unmarshaler/unmarshaler_test.go @@ -32,6 +32,32 @@ func TestUnmarshal(t *testing.T) { } }, }, + { + desc: "kv bool true", + input: `A = true`, + gen: func() test { + type doc struct { + A bool + } + return test{ + &doc{}, + &doc{A: true}, + } + }, + }, + { + desc: "kv bool false", + input: `A = false`, + gen: func() test { + type doc struct { + A bool + } + return test{ + &doc{A: true}, + &doc{A: false}, + } + }, + }, { desc: "string array", input: `A = ["foo", "bar"]`,