func (s *scope) setKeys(src, dest interface{}) {
	s.srcStack.top().key = fmt.Sprintf(`["%v"]`, src)
	s.destStack.top().key = fmt.Sprintf(`["%v"]`, dest)
}
Formats src & dest as map keys for printing.
package conversion
import (
	"fmt"
	"reflect"
)
type typePair struct {
	source reflect.Type
	dest   reflect.Type
}
type typeNamePair struct {
	fieldType reflect.Type
	fieldName string
}
type DebugLogger interface {
	Logf(format string, args ...interface{})
}
type NameFunc func(t reflect.Type) string
var DefaultNameFunc = func(t reflect.Type) string { return t.Name() }
type ConversionFunc func(a, b interface{}, scope Scope) error
type Converter struct {
	conversionFuncs          ConversionFuncs
	generatedConversionFuncs ConversionFuncs
	ignoredConversions map[typePair]struct{}
	structFieldDests map[typeNamePair][]typeNamePair
	structFieldSources map[typeNamePair][]typeNamePair
	inputFieldMappingFuncs map[reflect.Type]FieldMappingFunc
	inputDefaultFlags map[reflect.Type]FieldMatchingFlags
	Debug DebugLogger
	nameFunc func(t reflect.Type) string
}
func NewConverter(nameFn NameFunc) *Converter {
	c := &Converter{
		conversionFuncs:          NewConversionFuncs(),
		generatedConversionFuncs: NewConversionFuncs(),
		ignoredConversions:       make(map[typePair]struct{}),
		nameFunc:                 nameFn,
		structFieldDests:         make(map[typeNamePair][]typeNamePair),
		structFieldSources:       make(map[typeNamePair][]typeNamePair),
		inputFieldMappingFuncs: make(map[reflect.Type]FieldMappingFunc),
		inputDefaultFlags:      make(map[reflect.Type]FieldMatchingFlags),
	}
	c.RegisterConversionFunc(Convert_Slice_byte_To_Slice_byte)
	return c
}
func (c *Converter) WithConversions(fns ConversionFuncs) *Converter {
	copied := *c
	copied.conversionFuncs = c.conversionFuncs.Merge(fns)
	return &copied
}
func (c *Converter) DefaultMeta(t reflect.Type) (FieldMatchingFlags, *Meta) {
	return c.inputDefaultFlags[t], &Meta{
		KeyNameMapping: c.inputFieldMappingFuncs[t],
	}
}
func Convert_Slice_byte_To_Slice_byte(in *[]byte, out *[]byte, s Scope) error {
	if *in == nil {
		*out = nil
		return nil
	}
	*out = make([]byte, len(*in))
	copy(*out, *in)
	return nil
}
type Scope interface {
	Convert(src, dest interface{}, flags FieldMatchingFlags) error
	DefaultConvert(src, dest interface{}, flags FieldMatchingFlags) error
	SrcTag() reflect.StructTag
	DestTag() reflect.StructTag
	Flags() FieldMatchingFlags
	Meta() *Meta
}
type FieldMappingFunc func(key string, sourceTag, destTag reflect.StructTag) (source string, dest string)
func NewConversionFuncs() ConversionFuncs {
	return ConversionFuncs{
		fns:     make(map[typePair]reflect.Value),
		untyped: make(map[typePair]ConversionFunc),
	}
}
type ConversionFuncs struct {
	fns     map[typePair]reflect.Value
	untyped map[typePair]ConversionFunc
}
func (c ConversionFuncs) Add(fns ...interface{}) error {
	for _, fn := range fns {
		fv := reflect.ValueOf(fn)
		ft := fv.Type()
		if err := verifyConversionFunctionSignature(ft); err != nil {
			return err
		}
		c.fns[typePair{ft.In(0).Elem(), ft.In(1).Elem()}] = fv
	}
	return nil
}
func (c ConversionFuncs) AddUntyped(a, b interface{}, fn ConversionFunc) error {
	tA, tB := reflect.TypeOf(a), reflect.TypeOf(b)
	if tA.Kind() != reflect.Ptr {
		return fmt.Errorf("the type %T must be a pointer to register as an untyped conversion", a)
	}
	if tB.Kind() != reflect.Ptr {
		return fmt.Errorf("the type %T must be a pointer to register as an untyped conversion", b)
	}
	c.untyped[typePair{tA, tB}] = fn
	return nil
}
func (c ConversionFuncs) Merge(other ConversionFuncs) ConversionFuncs {
	merged := NewConversionFuncs()
	for k, v := range c.fns {
		merged.fns[k] = v
	}
	for k, v := range other.fns {
		merged.fns[k] = v
	}
	for k, v := range c.untyped {
		merged.untyped[k] = v
	}
	for k, v := range other.untyped {
		merged.untyped[k] = v
	}
	return merged
}
type Meta struct {
	KeyNameMapping FieldMappingFunc
	Context interface{}
}
type scope struct {
	converter *Converter
	meta      *Meta
	flags     FieldMatchingFlags
	srcStack  scopeStack
	destStack scopeStack
}
type scopeStackElem struct {
	tag   reflect.StructTag
	value reflect.Value
	key   string
}
type scopeStack []scopeStackElem
func (s *scopeStack) pop() {
	n := len(*s)
	*s = (*s)[:n-1]
}
func (s *scopeStack) push(e scopeStackElem) {
	*s = append(*s, e)
}
func (s *scopeStack) top() *scopeStackElem {
	return &(*s)[len(*s)-1]
}
func (s scopeStack) describe() string {
	desc := ""
	if len(s) > 1 {
		desc = "(" + s[1].value.Type().String() + ")"
	}
	for i, v := range s {
		if i < 2 {
			continue
		}
		if v.key == "" {
			desc += fmt.Sprintf(".%v", v.value.Type())
		} else {
			desc += fmt.Sprintf(".%v", v.key)
		}
	}
	return desc
}
func (s *scope) setIndices(src, dest int) {
	s.srcStack.top().key = fmt.Sprintf("[%v]", src)
	s.destStack.top().key = fmt.Sprintf("[%v]", dest)
}