mirror of
https://github.com/danog/liquid.git
synced 2024-11-30 07:58:58 +01:00
Rearrange value methods w/in file
This commit is contained in:
parent
9852226d22
commit
62f44fa728
@ -15,7 +15,7 @@ func (v structValue) Contains(elem Value) bool {
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
rt := reflect.TypeOf(v.basis)
|
||||
rt := reflect.TypeOf(v.value)
|
||||
if rt.Kind() == reflect.Ptr {
|
||||
if _, found := rt.MethodByName(name); found {
|
||||
return true
|
||||
@ -36,8 +36,8 @@ func (v structValue) PropertyValue(index Value) Value {
|
||||
if !ok {
|
||||
return nilValue
|
||||
}
|
||||
rv := reflect.ValueOf(v.basis)
|
||||
rt := reflect.TypeOf(v.basis)
|
||||
rv := reflect.ValueOf(v.value)
|
||||
rt := reflect.TypeOf(v.value)
|
||||
if rt.Kind() == reflect.Ptr {
|
||||
if _, found := rt.MethodByName(name); found {
|
||||
m := rv.MethodByName(name)
|
||||
@ -67,7 +67,7 @@ const tagKey = "liquid"
|
||||
|
||||
// like FieldByName, but obeys `liquid:"name"` tags
|
||||
func (v structValue) findField(name string) (*reflect.StructField, bool) {
|
||||
rt := reflect.TypeOf(v.basis)
|
||||
rt := reflect.TypeOf(v.value)
|
||||
if rt.Kind() == reflect.Ptr {
|
||||
rt = rt.Elem()
|
||||
}
|
||||
|
@ -37,6 +37,10 @@ func ValueOf(value interface{}) Value { // nolint: gocyclo
|
||||
return trueValue
|
||||
case false:
|
||||
return falseValue
|
||||
case 0:
|
||||
return zeroValue
|
||||
case 1:
|
||||
return oneValue
|
||||
}
|
||||
// interfaces
|
||||
switch v := value.(type) {
|
||||
@ -47,11 +51,7 @@ func ValueOf(value interface{}) Value { // nolint: gocyclo
|
||||
case Value:
|
||||
return v
|
||||
}
|
||||
rk := reflect.TypeOf(value).Kind()
|
||||
if rk <= reflect.Float64 {
|
||||
return wrapperValue{value}
|
||||
}
|
||||
switch rk {
|
||||
switch reflect.TypeOf(value).Kind() {
|
||||
case reflect.Ptr:
|
||||
rv := reflect.ValueOf(value)
|
||||
if rv.Type().Elem().Kind() == reflect.Struct {
|
||||
@ -77,7 +77,7 @@ const (
|
||||
sizeKey = "size"
|
||||
)
|
||||
|
||||
// embed this in a struct to give it default implementations of the Value interface
|
||||
// embed this in a struct to "inherit" default implementations of the Value interface
|
||||
type valueEmbed struct{}
|
||||
|
||||
func (v valueEmbed) Equal(Value) bool { return false }
|
||||
@ -85,38 +85,41 @@ func (v valueEmbed) Less(Value) bool { return false }
|
||||
func (v valueEmbed) IndexValue(Value) Value { return nilValue }
|
||||
func (v valueEmbed) Contains(Value) bool { return false }
|
||||
func (v valueEmbed) Int() int { panic(conversionError("", v, reflect.TypeOf(1))) }
|
||||
func (v valueEmbed) Interface() interface{} { return nil }
|
||||
func (v valueEmbed) PropertyValue(Value) Value { return nilValue }
|
||||
func (v valueEmbed) Test() bool { return true }
|
||||
|
||||
type wrapperValue struct{ basis interface{} }
|
||||
// A wrapperValue wraps a Go value.
|
||||
type wrapperValue struct{ value interface{} }
|
||||
|
||||
func (v wrapperValue) Equal(other Value) bool { return Equal(v.basis, other.Interface()) }
|
||||
func (v wrapperValue) Less(other Value) bool { return Less(v.basis, other.Interface()) }
|
||||
func (v wrapperValue) Equal(other Value) bool { return Equal(v.value, other.Interface()) }
|
||||
func (v wrapperValue) Less(other Value) bool { return Less(v.value, other.Interface()) }
|
||||
func (v wrapperValue) IndexValue(Value) Value { return nilValue }
|
||||
func (v wrapperValue) Contains(Value) bool { return false }
|
||||
func (v wrapperValue) Interface() interface{} { return v.basis }
|
||||
func (v wrapperValue) Interface() interface{} { return v.value }
|
||||
func (v wrapperValue) PropertyValue(Value) Value { return nilValue }
|
||||
func (v wrapperValue) Test() bool { return v.basis != nil && v.basis != false }
|
||||
func (v wrapperValue) Test() bool { return v.value != nil && v.value != false }
|
||||
|
||||
func (v wrapperValue) Int() int {
|
||||
if n, ok := v.basis.(int); ok {
|
||||
if n, ok := v.value.(int); ok {
|
||||
return n
|
||||
}
|
||||
panic(conversionError("", v.basis, reflect.TypeOf(1)))
|
||||
panic(conversionError("", v.value, reflect.TypeOf(1)))
|
||||
}
|
||||
|
||||
// interned values
|
||||
var nilValue = wrapperValue{nil}
|
||||
var falseValue = wrapperValue{false}
|
||||
var trueValue = wrapperValue{true}
|
||||
var zeroValue = wrapperValue{0}
|
||||
var oneValue = wrapperValue{1}
|
||||
|
||||
// container values
|
||||
type arrayValue struct{ wrapperValue }
|
||||
type mapValue struct{ wrapperValue }
|
||||
type stringValue struct{ wrapperValue }
|
||||
|
||||
func (v arrayValue) Contains(elem Value) bool {
|
||||
rv := reflect.ValueOf(v.basis)
|
||||
rv := reflect.ValueOf(v.value)
|
||||
e := elem.Interface()
|
||||
for i, len := 0, rv.Len(); i < len; i++ {
|
||||
if Equal(rv.Index(i).Interface(), e) {
|
||||
@ -126,31 +129,14 @@ func (v arrayValue) Contains(elem Value) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (v mapValue) Contains(index Value) bool {
|
||||
rv := reflect.ValueOf(v.basis)
|
||||
iv := reflect.ValueOf(index.Interface())
|
||||
if rv.Type().Key() == iv.Type() {
|
||||
return rv.MapIndex(iv).IsValid()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (v stringValue) Contains(substr Value) bool {
|
||||
s, ok := substr.Interface().(string)
|
||||
if !ok {
|
||||
s = fmt.Sprint(substr.Interface())
|
||||
}
|
||||
return strings.Contains(v.basis.(string), s)
|
||||
}
|
||||
|
||||
func (v arrayValue) IndexValue(index Value) Value {
|
||||
rv := reflect.ValueOf(v.basis)
|
||||
rv := reflect.ValueOf(v.value)
|
||||
var n int
|
||||
switch ix := index.Interface().(type) {
|
||||
case int:
|
||||
n = ix
|
||||
case float32:
|
||||
// this how Ruby arrays, and therefore Liquid arrays, work
|
||||
// Ruby array indexing truncates floats
|
||||
n = int(ix)
|
||||
case float64:
|
||||
n = int(ix)
|
||||
@ -166,20 +152,8 @@ func (v arrayValue) IndexValue(index Value) Value {
|
||||
return nilValue
|
||||
}
|
||||
|
||||
func (v mapValue) IndexValue(index Value) Value {
|
||||
rv := reflect.ValueOf(v.basis)
|
||||
iv := reflect.ValueOf(index.Interface())
|
||||
if iv.IsValid() && iv.Type().ConvertibleTo(rv.Type().Key()) {
|
||||
ev := rv.MapIndex(iv.Convert(rv.Type().Key()))
|
||||
if ev.IsValid() {
|
||||
return ValueOf(ev.Interface())
|
||||
}
|
||||
}
|
||||
return nilValue
|
||||
}
|
||||
|
||||
func (v arrayValue) PropertyValue(index Value) Value {
|
||||
rv := reflect.ValueOf(v.basis)
|
||||
rv := reflect.ValueOf(v.value)
|
||||
switch index.Interface() {
|
||||
case firstKey:
|
||||
if rv.Len() > 0 {
|
||||
@ -195,6 +169,27 @@ func (v arrayValue) PropertyValue(index Value) Value {
|
||||
return nilValue
|
||||
}
|
||||
|
||||
func (v mapValue) Contains(index Value) bool {
|
||||
rv := reflect.ValueOf(v.value)
|
||||
iv := reflect.ValueOf(index.Interface())
|
||||
if rv.Type().Key() == iv.Type() {
|
||||
return rv.MapIndex(iv).IsValid()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (v mapValue) IndexValue(index Value) Value {
|
||||
rv := reflect.ValueOf(v.value)
|
||||
iv := reflect.ValueOf(index.Interface())
|
||||
if iv.IsValid() && iv.Type().ConvertibleTo(rv.Type().Key()) {
|
||||
ev := rv.MapIndex(iv.Convert(rv.Type().Key()))
|
||||
if ev.IsValid() {
|
||||
return ValueOf(ev.Interface())
|
||||
}
|
||||
}
|
||||
return nilValue
|
||||
}
|
||||
|
||||
func (v mapValue) PropertyValue(index Value) Value {
|
||||
rv := reflect.ValueOf(v.Interface())
|
||||
iv := reflect.ValueOf(index.Interface())
|
||||
@ -212,9 +207,17 @@ func (v mapValue) PropertyValue(index Value) Value {
|
||||
}
|
||||
}
|
||||
|
||||
func (v stringValue) Contains(substr Value) bool {
|
||||
s, ok := substr.Interface().(string)
|
||||
if !ok {
|
||||
s = fmt.Sprint(substr.Interface())
|
||||
}
|
||||
return strings.Contains(v.value.(string), s)
|
||||
}
|
||||
|
||||
func (v stringValue) PropertyValue(index Value) Value {
|
||||
if index.Interface() == sizeKey {
|
||||
return ValueOf(len(v.basis.(string)))
|
||||
return ValueOf(len(v.value.(string)))
|
||||
}
|
||||
return nilValue
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user