Skip to content

Commit

Permalink
adds std encoding API fixes hashicorp#4
Browse files Browse the repository at this point in the history
The std encoding format is Unmarshal([]byte, interface{}) error.
This naturally lends itself well to being passed readfile or exhausted
reader/buffer.
  • Loading branch information
drewwells authored and sethvargo committed Mar 10, 2016
1 parent 5b00661 commit 2799afc
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 12 deletions.
11 changes: 11 additions & 0 deletions decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@ var (
nodeType reflect.Type = findNodeType()
)

// Unmarshal accepts a byte slice as input and writes the
// data to the value pointed to by v.
func Unmarshal(bs []byte, v interface{}) error {
root, err := parse(bs)
if err != nil {
return err
}

return DecodeObject(v, root)
}

// Decode reads the given input and decodes it into the structure
// given by `out`.
func Decode(out interface{}, in string) error {
Expand Down
10 changes: 10 additions & 0 deletions decoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,16 @@ func TestDecode_interface(t *testing.T) {
if !reflect.DeepEqual(out, tc.Out) {
t.Fatalf("Input: %s. Actual, Expected.\n\n%#v\n\n%#v", tc.File, out, tc.Out)
}

var v interface{}
err = Unmarshal(d, &v)
if (err != nil) != tc.Err {
t.Fatalf("Input: %s\n\nError: %s", tc.File, err)
}

if !reflect.DeepEqual(v, tc.Out) {
t.Fatalf("Input: %s. Actual, Expected.\n\n%#v\n\n%#v", tc.File, out, tc.Out)
}
}
}

Expand Down
17 changes: 12 additions & 5 deletions lex.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package hcl

import (
"unicode"
"unicode/utf8"
)

type lexModeValue byte
Expand All @@ -14,17 +15,23 @@ const (

// lexMode returns whether we're going to be parsing in JSON
// mode or HCL mode.
func lexMode(v string) lexModeValue {
for _, r := range v {
func lexMode(v []byte) lexModeValue {
var (
r rune
w int
offset int
)

for {
r, w = utf8.DecodeRune(v[offset:])
offset += w
if unicode.IsSpace(r) {
continue
}

if r == '{' {
return lexModeJson
} else {
return lexModeHcl
}
break
}

return lexModeHcl
Expand Down
2 changes: 1 addition & 1 deletion lex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func TestLexMode(t *testing.T) {
}

for i, tc := range cases {
actual := lexMode(tc.Input)
actual := lexMode([]byte(tc.Input))

if actual != tc.Mode {
t.Fatalf("%d: %#v", i, actual)
Expand Down
28 changes: 22 additions & 6 deletions parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,32 @@ import (
jsonParser "github.com/hashicorp/hcl/json/parser"
)

// Parse parses the given input and returns the root object.
// ParseBytes accepts as input byte slice and returns ast tree.
//
// The input format can be either HCL or JSON.
func Parse(input string) (*ast.File, error) {
switch lexMode(input) {
// Input can be either JSON or HCL
func ParseBytes(in []byte) (*ast.File, error) {
return parse(in)
}

// ParseString accepts input as a string and returns ast tree.
func ParseString(input string) (*ast.File, error) {
return parse([]byte(input))
}

func parse(in []byte) (*ast.File, error) {
switch lexMode(in) {
case lexModeHcl:
return hclParser.Parse([]byte(input))
return hclParser.Parse(in)
case lexModeJson:
return jsonParser.Parse([]byte(input))
return jsonParser.Parse(in)
}

return nil, fmt.Errorf("unknown config format")
}

// Parse parses the given input and returns the root object.
//
// The input format can be either HCL or JSON.
func Parse(input string) (*ast.File, error) {
return parse([]byte(input))
}

0 comments on commit 2799afc

Please sign in to comment.