decoder structure for future options
This commit is contained in:
parent
5a08b50877
commit
58215e2ffa
35
decoder.go
35
decoder.go
@ -21,10 +21,13 @@ func Decode(out interface{}, in string) error {
|
|||||||
// DecodeAST is a lower-level version of Decode. It decodes a
|
// DecodeAST is a lower-level version of Decode. It decodes a
|
||||||
// raw AST into the given output.
|
// raw AST into the given output.
|
||||||
func DecodeAST(out interface{}, obj *ast.ObjectNode) error {
|
func DecodeAST(out interface{}, obj *ast.ObjectNode) error {
|
||||||
return decode("root", *obj, reflect.ValueOf(out).Elem())
|
var d decoder
|
||||||
|
return d.decode("root", *obj, reflect.ValueOf(out).Elem())
|
||||||
}
|
}
|
||||||
|
|
||||||
func decode(name string, n ast.Node, result reflect.Value) error {
|
type decoder struct{}
|
||||||
|
|
||||||
|
func (d *decoder) decode(name string, n ast.Node, result reflect.Value) error {
|
||||||
k := result
|
k := result
|
||||||
|
|
||||||
// If we have an interface with a valid value, we use that
|
// If we have an interface with a valid value, we use that
|
||||||
@ -38,16 +41,16 @@ func decode(name string, n ast.Node, result reflect.Value) error {
|
|||||||
|
|
||||||
switch k.Kind() {
|
switch k.Kind() {
|
||||||
case reflect.Int:
|
case reflect.Int:
|
||||||
return decodeInt(name, n, result)
|
return d.decodeInt(name, n, result)
|
||||||
case reflect.Interface:
|
case reflect.Interface:
|
||||||
// When we see an interface, we make our own thing
|
// When we see an interface, we make our own thing
|
||||||
return decodeInterface(name, n, result)
|
return d.decodeInterface(name, n, result)
|
||||||
case reflect.Map:
|
case reflect.Map:
|
||||||
return decodeMap(name, n, result)
|
return d.decodeMap(name, n, result)
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
return decodeSlice(name, n, result)
|
return d.decodeSlice(name, n, result)
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
return decodeString(name, n, result)
|
return d.decodeString(name, n, result)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("%s: unknown kind: %s", name, result.Kind())
|
return fmt.Errorf("%s: unknown kind: %s", name, result.Kind())
|
||||||
}
|
}
|
||||||
@ -55,7 +58,7 @@ func decode(name string, n ast.Node, result reflect.Value) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeInt(name string, raw ast.Node, result reflect.Value) error {
|
func (d *decoder) decodeInt(name string, raw ast.Node, result reflect.Value) error {
|
||||||
n, ok := raw.(ast.LiteralNode)
|
n, ok := raw.(ast.LiteralNode)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("%s: not a literal type", name)
|
return fmt.Errorf("%s: not a literal type", name)
|
||||||
@ -71,7 +74,7 @@ func decodeInt(name string, raw ast.Node, result reflect.Value) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeInterface(name string, raw ast.Node, result reflect.Value) error {
|
func (d *decoder) decodeInterface(name string, raw ast.Node, result reflect.Value) error {
|
||||||
var set reflect.Value
|
var set reflect.Value
|
||||||
redecode := true
|
redecode := true
|
||||||
|
|
||||||
@ -98,7 +101,7 @@ func decodeInterface(name string, raw ast.Node, result reflect.Value) error {
|
|||||||
|
|
||||||
for _, elem := range n.Elem {
|
for _, elem := range n.Elem {
|
||||||
raw := new(interface{})
|
raw := new(interface{})
|
||||||
err := decode(
|
err := d.decode(
|
||||||
name, elem, reflect.Indirect(reflect.ValueOf(raw)))
|
name, elem, reflect.Indirect(reflect.ValueOf(raw)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -133,7 +136,7 @@ func decodeInterface(name string, raw ast.Node, result reflect.Value) error {
|
|||||||
if redecode {
|
if redecode {
|
||||||
// Revisit the node so that we can use the newly instantiated
|
// Revisit the node so that we can use the newly instantiated
|
||||||
// thing and populate it.
|
// thing and populate it.
|
||||||
if err := decode(name, raw, result); err != nil {
|
if err := d.decode(name, raw, result); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,7 +144,7 @@ func decodeInterface(name string, raw ast.Node, result reflect.Value) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeMap(name string, raw ast.Node, result reflect.Value) error {
|
func (d *decoder) decodeMap(name string, raw ast.Node, result reflect.Value) error {
|
||||||
obj, ok := raw.(ast.ObjectNode)
|
obj, ok := raw.(ast.ObjectNode)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("%s: not an object type", name)
|
return fmt.Errorf("%s: not an object type", name)
|
||||||
@ -195,7 +198,7 @@ func decodeMap(name string, raw ast.Node, result reflect.Value) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Decode!
|
// Decode!
|
||||||
if err := decode(fieldName, objValue, val); err != nil {
|
if err := d.decode(fieldName, objValue, val); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +211,7 @@ func decodeMap(name string, raw ast.Node, result reflect.Value) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeSlice(name string, raw ast.Node, result reflect.Value) error {
|
func (d *decoder) decodeSlice(name string, raw ast.Node, result reflect.Value) error {
|
||||||
n, ok := raw.(ast.ListNode)
|
n, ok := raw.(ast.ListNode)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("%s: not a list type", name)
|
return fmt.Errorf("%s: not a list type", name)
|
||||||
@ -235,7 +238,7 @@ func decodeSlice(name string, raw ast.Node, result reflect.Value) error {
|
|||||||
|
|
||||||
// Decode
|
// Decode
|
||||||
val := reflect.Indirect(reflect.New(resultElemType))
|
val := reflect.Indirect(reflect.New(resultElemType))
|
||||||
if err := decode(fieldName, elem, val); err != nil {
|
if err := d.decode(fieldName, elem, val); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +250,7 @@ func decodeSlice(name string, raw ast.Node, result reflect.Value) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeString(name string, raw ast.Node, result reflect.Value) error {
|
func (d *decoder) decodeString(name string, raw ast.Node, result reflect.Value) error {
|
||||||
n, ok := raw.(ast.LiteralNode)
|
n, ok := raw.(ast.LiteralNode)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("%s: not a literal type", name)
|
return fmt.Errorf("%s: not a literal type", name)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user