Skip to content

Commit

Permalink
supporting array of maps and also only parsing interface as map rathe…
Browse files Browse the repository at this point in the history
…r than trying to parse as actual struct
  • Loading branch information
Pungyeon committed Jan 20, 2021
1 parent 8063d8a commit f63f0d7
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 10 deletions.
21 changes: 11 additions & 10 deletions pkg/json/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,14 @@ func (p *parser) decodeArray(arr reflect.Value) error {
return nil
case token.OpenCurly:
arr.Set(grow(arr, i))
if err := p.decodeObject(arr.Index(i), tags); err != nil {
return err
if arr.Index(i).Kind() == reflect.Map {
if err := p.decodeMap(arr.Index(i)); err != nil {
return err
}
} else {
if err := p.decodeObject(arr.Index(i), tags); err != nil {
return err
}
}
i++
if p.current().Type == token.ClosingBrace {
Expand Down Expand Up @@ -260,8 +266,9 @@ func (p *parser) parseArray(sliceType reflect.Type) (reflect.Value, error) {
case token.ClosingBrace:
return arr.Slice(0, i), nil
case token.OpenCurly:
if err := p.parseStructure(val); err != nil {
return val, nil
val, err := p.parseMap(val.Type())
if err != nil {
return val, err
}
arr = insertAt(arr, i, val)
i++
Expand Down Expand Up @@ -332,12 +339,6 @@ func (p *parser) parseStructure(vo reflect.Value) error {
}
tags.Set(tag) // TODO : Make sure to not set this, if the token is a NullToken
obj.Set(val)
// TODO : This is currently 10+ allocations per op :/
if req, ok := obj.Interface().(required.Required); ok {
if err := req.IsValueValid(); err != nil {
return err
}
}
}
if p.eof() || p.current().Type == token.ClosingCurly {
p.next()
Expand Down
28 changes: 28 additions & 0 deletions pkg/json/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -533,3 +533,31 @@ func TestCustomMarshaler(t *testing.T) {
t.Fatal(d.Value)
}
}

func TestMapArray(t *testing.T) {
type MA struct {
Array []map[string]int
}

var ma MA
if err := Parse(LexString(t, `{ "array": [{ "name": 3 }]`), &ma); err != nil {
t.Fatal(err)
}
if ma.Array[0]["name"] != 3 {
t.Fatal(ma)
}
}

func TestMapArrayInterface(t *testing.T) {
type MA struct {
Array []map[string]int
}

var ma interface{}
if err := Parse(LexString(t, `{ "array": [{ "name": 3 }]`), &ma); err != nil {
t.Fatal(err)
}
if ma.(map[string]interface{})["array"].([]interface{})[0].(map[string]interface{})["name"].(int) != 3 {
t.Fatal(ma)
}
}

0 comments on commit f63f0d7

Please sign in to comment.