env.go 3.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
package expr

import "reflect"

// Assertions.
var (
	_ = TypeResolver(&TypeResolverAdapter{})
	_ = TypeResolver(&MetaTypeResolver{})
	_ = Resolver(&MetaResolver{})
	_ = TypeResolver(&StructTypeResolver{})
	_ = Resolver(&StructResolver{})
	_ = TypeResolver(&MapTypeResolver{})
	_ = Resolver(&MapResolver{})
)

// TypeResolver resolves types.
type TypeResolver interface {
	TypeResolve(ident string) Type
}

// Resolver resolves runtime values.
type Resolver interface {
	Resolve(ident string) Value
}

// TypeResolverAdapter adapts a runtime resolver to a type resolver by taking
// types of values retrieve from Resolve.
type TypeResolverAdapter struct {
	Resolver
}

// NewTypeResolverAdapter creates a new TypeResolverAdapter from a resolver.
func NewTypeResolverAdapter(r Resolver) *TypeResolverAdapter {
	return &TypeResolverAdapter{r}
}

// TypeResolve implements TypeResolver.
func (r *TypeResolverAdapter) TypeResolve(ident string) Type {
	return r.Resolve(ident).Type()
}

// MetaTypeResolver runs multiple type resolvers serially.
type MetaTypeResolver struct {
	resolvers []TypeResolver
}

// NewMetaTypeResolver creates a new meta type resolver.
func NewMetaTypeResolver() *MetaTypeResolver {
	return &MetaTypeResolver{}
}

// AddResolver adds a new resolver below other resolvers.
func (r *MetaTypeResolver) AddResolver(n TypeResolver) {
	r.resolvers = append(r.resolvers, n)
}

// TypeResolve implements TypeResolver.
func (r *MetaTypeResolver) TypeResolve(ident string) Type {
	for _, resolver := range r.resolvers {
		if t := resolver.TypeResolve(ident); t != nil {
			return t
		}
	}
	return nil
}

// MetaResolver runs multiple resolvers serially.
type MetaResolver struct {
	resolvers []Resolver
}

// NewMetaResolver creates a new meta resolver.
func NewMetaResolver() *MetaResolver {
	return &MetaResolver{}
}

// AddResolver adds a new resolver below other resolvers.
func (r *MetaResolver) AddResolver(n Resolver) {
	r.resolvers = append(r.resolvers, n)
}

// Resolve implements Resolver.
func (r *MetaResolver) Resolve(ident string) Value {
	for _, resolver := range r.resolvers {
		if t := resolver.Resolve(ident); t != nil {
			return t
		}
	}
	return nil
}

// StructTypeResolver resolves types of struct fields.
type StructTypeResolver struct {
	struc *StructType
}

// NewStructTypeResolver creates a new struct type resolver.
func NewStructTypeResolver(s interface{}) *StructTypeResolver {
	return &StructTypeResolver{TypeOf(s).(*StructType)}
}

// TypeResolve implements TypeResolver.
func (r *StructTypeResolver) TypeResolve(ident string) Type {
	if f, ok := r.struc.FieldByName(ident); ok {
		return f.Type
	}
	return nil
}

// StructResolver resolves struct fields.
type StructResolver struct {
	struc reflect.Value
}

// NewStructResolver creates a new struct resolver.
func NewStructResolver(s reflect.Value) *StructResolver {
	return &StructResolver{s}
}

// Resolve implements Resolver.
func (r *StructResolver) Resolve(ident string) Value {
	if sv := r.struc.FieldByName(ident); sv.IsValid() {
		return ValueOf(sv.Interface())
	}
	return nil
}

// MapTypeResolver resolves map keys.
type MapTypeResolver struct {
	m map[string]Type
}

// NewMapTypeResolver creates a new struct resolver.
func NewMapTypeResolver(m map[string]Type) *MapTypeResolver {
	return &MapTypeResolver{m}
}

// TypeResolve implements TypeResolver.
func (r *MapTypeResolver) TypeResolve(ident string) Type {
	if t, ok := r.m[ident]; ok {
		return t
	}
	return nil
}

// MapResolver resolves map keys.
type MapResolver struct {
	m map[string]Value
}

// NewMapResolver creates a new struct resolver.
func NewMapResolver(m map[string]Value) *MapResolver {
	return &MapResolver{m}
}

// Resolve implements Resolver.
func (r *MapResolver) Resolve(ident string) Value {
	if v, ok := r.m[ident]; ok {
		return v
	}
	return nil
}