예제 #1
0
파일: trim.go 프로젝트: katydid/v0.1
func trim(f interface{}) (interface{}, error) {
	if reflect.TypeOf(f).Implements(varTyp) {
		return f, nil
	}
	if reflect.TypeOf(f).Implements(constTyp) {
		return f, nil
	}
	this := reflect.ValueOf(f).Elem()
	trimable := true
	for i := 0; i < this.NumField(); i++ {
		var trimmed interface{}
		var err error
		if this.Field(i).Type().Kind() == reflect.Slice {
			if _, ok := this.Field(i).Type().Elem().MethodByName("Eval"); ok {
				trimable = false
			}
		}
		if _, ok := this.Field(i).Type().MethodByName("Eval"); !ok {
			continue
		}
		if this.Field(i).Elem().Type().Implements(varTyp) {
			if funcs.IsConst(this.Field(i).Type()) {
				return nil, &errNotConst{f, this.Field(i)}
			}
			trimable = false
			continue
		}
		if this.Field(i).Elem().Type().Implements(listOfTyp) {
			trimmed, err = trimList(this.Field(i).Interface())
		} else {
			trimmed, err = trim(this.Field(i).Interface())
		}
		if err != nil {
			return nil, err
		}
		this.Field(i).Set(reflect.ValueOf(trimmed))
		if !this.Field(i).Elem().Type().Implements(constTyp) {
			if funcs.IsConst(this.Field(i).Type()) {
				return nil, &errNotConst{f, this.Field(i)}
			}
			trimable = false
		}
	}
	if !trimable {
		return f, nil
	}
	if inits, ok := f.(funcs.Init); ok {
		err := inits.Init()
		if err != nil {
			return nil, err
		}
	}
	return funcs.NewConst(reflect.ValueOf(f).MethodByName("Eval").Call(nil)[0].Interface()), nil
}
예제 #2
0
파일: trim.go 프로젝트: katydid/v0.1
func trimList(f interface{}) (interface{}, error) {
	this := reflect.ValueOf(f).Elem()
	list := this.Field(0)
	newList := reflect.MakeSlice(list.Type(), list.Len(), list.Len())
	trimable := true
	for i := 0; i < list.Len(); i++ {
		trimmed, err := trim(list.Index(i).Interface())
		if err != nil {
			return nil, err
		}
		trimmedValue := reflect.ValueOf(trimmed)
		newList.Index(i).Set(trimmedValue)
		if !trimmedValue.Type().Implements(constTyp) {
			trimable = false
		}
	}
	this.Field(0).Set(newList)
	if !trimable {
		return f, nil
	}
	return funcs.NewConst(reflect.ValueOf(f).MethodByName("Eval").Call(nil)[0].Interface()), nil
}