Skip to content

katydid/parser-go-reflect

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

528 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

parser-go-reflect

Reflection based parser for Go.

We can dynamically walk over reflecting Go structs using the Parser interface:

import (
    "reflect"
    reflectparser "github.com/katydid/parser-go-reflect/reflect"
)

func main() {
	mystruct := &MyStruct{MyField: "myvalue", OtherField: "othervalue"}
    parser := reflectparser.NewParser()
	parser.Init(reflect.ValueOf(mystruct))
	myvalue, err := GetMyField(parser)
	if err != nil {
		panic(err)
	}
	println(myvalue)
}

We can then use the parser to decode only MyField and skip over other fields and return "myvalue":

import (
	"errors"
	"github.com/katydid/parser-go/cast"
	"github.com/katydid/parser-go/parse"
)

func GetMyField(p parse.Parser) (string, error) {
	hint, err := p.Next()
	if hint != parse.EnterHint {
		return "", errors.New("expected object")
	}
	if err != nil {
		return "", err
	}
	for {
		hint, err = p.Next()
		if err != nil {
			return "", err
		}
		if hint != parse.FieldHint {
			return "", errors.New("expected field")
		}
		kind, fieldName, err := p.Token()
		if err != nil {
			return "", err
		}
		if kind != parse.StringKind {
			return "", errors.New("expected string")
		}
		if cast.ToString(fieldName) == "MyField" {
			hint, err = p.Next()
			if err != nil {
				return "", err
			}
			if hint != parse.ValueHint {
				return "", errors.New("expected field")
			}
			kind, val, err := p.Token()
			if err != nil {
				return "", err
			}
			if kind != parse.StringKind {
				return "", errors.New("expected string")
			}
			return cast.ToString(val), nil
		} else {
			p.Skip()
		}
	}
}

About

Reflection based parser in Go

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors