func (s *Scheme) ConvertToVersion(in interface{}, outVersion string) (interface{}, error) {
	t := reflect.TypeOf(in)
	if t.Kind() != reflect.Ptr {
		return nil, fmt.Errorf("only pointer types may be converted: %v", t)
	}
	t = t.Elem()
	if t.Kind() != reflect.Struct {
		return nil, fmt.Errorf("only pointers to struct types may be converted: %v", t)
	}
	kinds, ok := s.typeToKind[t]
	if !ok {
		return nil, fmt.Errorf("%v cannot be converted into version %q", t, outVersion)
	}
	outKind := kinds[0]
	inVersion, _, err := s.ObjectVersionAndKind(in)
	if err != nil {
		return nil, err
	}
	out, err := s.NewObject(outVersion, outKind)
	if err != nil {
		return nil, err
	}
	if err := s.converter.Convert(in, out, 0, s.generateConvertMeta(inVersion, outVersion)); err != nil {
		return nil, err
	}
	if err := s.SetVersionAndKind(outVersion, outKind, out); err != nil {
		return nil, err
	}
	return out, nil
}
ConvertToVersion attempts to convert an input object to its matching Kind in another
version within this scheme. Will return an error if the provided version does not
contain the inKind (or a mapping by name defined with AddKnownTypeWithName).
package conversion
import (
	"fmt"
	"reflect"
)
type Scheme struct {
	versionMap map[string]map[string]reflect.Type
	typeToVersion map[reflect.Type]string
	typeToKind map[reflect.Type][]string
	converter *Converter
	Indent bool
	InternalVersion string
	MetaFactory MetaFactory
}
func NewScheme() *Scheme {
	s := &Scheme{
		versionMap:      map[string]map[string]reflect.Type{},
		typeToVersion:   map[reflect.Type]string{},
		typeToKind:      map[reflect.Type][]string{},
		converter:       NewConverter(),
		InternalVersion: "",
		MetaFactory:     DefaultMetaFactory,
	}
	s.converter.nameFunc = s.nameFunc
	return s
}
func (s *Scheme) Log(l DebugLogger) {
	s.converter.Debug = l
}
func (s *Scheme) nameFunc(t reflect.Type) string {
	names, ok := s.typeToKind[t]
	if !ok {
		return t.Name()
	}
	if internal, ok := s.versionMap[""]; ok {
		for _, name := range names {
			if t, ok := internal[name]; ok {
				return s.typeToKind[t][0]
			}
		}
	}
	return names[0]
}
func (s *Scheme) AddKnownTypes(version string, types ...interface{}) {
	knownTypes, found := s.versionMap[version]
	if !found {
		knownTypes = map[string]reflect.Type{}
		s.versionMap[version] = knownTypes
	}
	for _, obj := range types {
		t := reflect.TypeOf(obj)
		if t.Kind() != reflect.Ptr {
			panic("All types must be pointers to structs.")
		}
		t = t.Elem()
		if t.Kind() != reflect.Struct {
			panic("All types must be pointers to structs.")
		}
		knownTypes[t.Name()] = t
		s.typeToVersion[t] = version
		s.typeToKind[t] = append(s.typeToKind[t], t.Name())
	}
}
func (s *Scheme) AddKnownTypeWithName(version, kind string, obj interface{}) {
	knownTypes, found := s.versionMap[version]
	if !found {
		knownTypes = map[string]reflect.Type{}
		s.versionMap[version] = knownTypes
	}
	t := reflect.TypeOf(obj)
	if t.Kind() != reflect.Ptr {
		panic("All types must be pointers to structs.")
	}
	t = t.Elem()
	if t.Kind() != reflect.Struct {
		panic("All types must be pointers to structs.")
	}
	knownTypes[kind] = t
	s.typeToVersion[t] = version
	s.typeToKind[t] = append(s.typeToKind[t], kind)
}
func (s *Scheme) KnownTypes(version string) map[string]reflect.Type {
	all, ok := s.versionMap[version]
	if !ok {
		return map[string]reflect.Type{}
	}
	types := make(map[string]reflect.Type)
	for k, v := range all {
		types[k] = v
	}
	return types
}
func (s *Scheme) NewObject(versionName, kind string) (interface{}, error) {
	if types, ok := s.versionMap[versionName]; ok {
		if t, ok := types[kind]; ok {
			return reflect.New(t).Interface(), nil
		}
		return nil, &notRegisteredErr{kind: kind, version: versionName}
	}
	return nil, &notRegisteredErr{kind: kind, version: versionName}
}
func (s *Scheme) AddConversionFuncs(conversionFuncs ...interface{}) error {
	for _, f := range conversionFuncs {
		if err := s.converter.RegisterConversionFunc(f); err != nil {
			return err
		}
	}
	return nil
}
func (s *Scheme) AddStructFieldConversion(srcFieldType interface{}, srcFieldName string, destFieldType interface{}, destFieldName string) error {
	return s.converter.SetStructFieldCopy(srcFieldType, srcFieldName, destFieldType, destFieldName)
}
func (s *Scheme) AddDefaultingFuncs(defaultingFuncs ...interface{}) error {
	for _, f := range defaultingFuncs {
		err := s.converter.RegisterDefaultingFunc(f)
		if err != nil {
			return err
		}
	}
	return nil
}
func (s *Scheme) Convert(in, out interface{}) error {
	inVersion := "unknown"
	outVersion := "unknown"
	if v, _, err := s.ObjectVersionAndKind(in); err == nil {
		inVersion = v
	}
	if v, _, err := s.ObjectVersionAndKind(out); err == nil {
		outVersion = v
	}
	return s.converter.Convert(in, out, AllowDifferentFieldTypeNames, s.generateConvertMeta(inVersion, outVersion))
}