func GetterValue(path string, in interface{}) (v interface{}, found bool) {
	defer func() {
		if x := recover(); x != nil {
			return
		}
	}()
	parts := strings.Split(path, ".")
	if len(parts) == 0 {
		return nil, false
	}
	var (
		parent   reflect.Value
		lastPart string
	)
	cur := reflect.ValueOf(in)
	for i, part := range parts {
		m := cur.MethodByName(part)
		typ := m.Type()
		if typ.NumIn() != 0 || typ.NumOut() != 1 {
			continue
		}
		out := m.Call(nil)
		parent = cur
		cur = out[0]
		if cur.NumMethod() == 0 && i != len(parts)-1 {
			return nil, false
		}
		lastPart = part
	}
	if cur.Kind() == reflect.String {
		m := parent.MethodByName(lastPart + "Bytes")
		if m.IsValid() {
			out := m.Call(nil)
			if vv := out[0]; vv.CanInterface() {
				v = vv.Interface()
				found = true
				return
			}
		}
	}
	v = cur.Interface()
	found = true
	return
}
GetterValue is a special case of FieldValue, that checks if for a field named Foo,
there is a method that is named FooBytes(). Useful to avoid allocations when accesing
string values that can be returned as a memory pointer instead (e.g. in capnproto).
package structwalk
import (
	"fmt"
	"reflect"
	"sort"
	"strings"
)
func FieldValue(path string, in interface{}) (v interface{}, found bool) {
	var cur reflect.Value
	cur, found = findValue(path, in)
	if !found {
		return
	}
	v, found = cur.Interface(), true
	return
}
func SetFieldValue(path string, v interface{}, in interface{}) {
	var cur reflect.Value
	cur, found := findValue(path, in)
	if !found {
		return
	}
	cur.Set(reflect.ValueOf(v))
}
func findValue(path string, in interface{}) (v reflect.Value, found bool) {
	defer func() {
		if x := recover(); x != nil {
			return
		}
	}()
	parts := strings.Split(path, ".")
	if len(parts) == 0 {
		return reflect.Value{}, false
	}
	cur := reflect.ValueOf(in)
	for i, part := range parts {
		part := strings.ToLower(part)
		for {
			if cur.Kind() == reflect.Ptr || cur.Kind() == reflect.Interface {
				cur = cur.Elem()
				continue
			}
			break
		}
		if cur.Kind() == reflect.Struct {
			cur = cur.FieldByNameFunc(func(name string) bool {
				return strings.ToLower(name) == part
			})
		} else if cur.Kind() == reflect.Map {
			keys := cur.MapKeys()
			var keyFound bool
			for _, k := range keys {
				if strings.ToLower(k.String()) == part {
					cur = cur.MapIndex(k)
					keyFound = true
					break
				}
			}
			if !keyFound {
				return reflect.Value{}, false
			}
		} else if i != len(parts)-1 {
			return reflect.Value{}, false
		}
	}
	return cur, true
}