예제 #1
0
파일: auto.go 프로젝트: ZxxLang/typeless
// 执行 val 到 to 类型, 并赋值到 to
func (p *Group) SetTo(to interface{}, args ...interface{}) (err error) {
	var val interface{}
	if len(args) > 0 {
		val = args[0]
	}
	v := proto.ValueOf(val)
	if !v.IsValid() {
		return toInValidArgs(v)
	}
	return nil
}
예제 #2
0
파일: auto.go 프로젝트: ZxxLang/typeless
// 执行 val 到 like 类型, 并返回 interface{},args 是附加的参数
func (p *Group) To(like interface{}, args ...interface{}) (i interface{}, err error) {
	defer func() {
		if e := recover(); e != nil {
			err = errors.New(fmt.Sprint(e))
		}
	}()
	if len(args) == 0 {
		return nil, toInValidArgs("arguments length is zero")
	}

	c := p.match(like, args)

	if c == nil {
		return nil, toNotSupported(like)
	}
	// 单函数
	if len(c.queue) == 0 {
		in := []reflect.Value{}
		for _, arg := range args {
			in = append(in, proto.ValueOf(arg))
		}
		out := c.apply.Call(in)
		ify := len(out) - 1
		if ify < 0 || out[0].Kind().String() != proto.TypeOf(like).Kind().String() {
			return nil, toFail(like)
		}
		switch c.ify {
		case "bool":
			if !out[ify].Bool() {
				return nil, toFail(like)
			}
		case "error":
			if !out[ify].IsNil() {
				return nil, out[ify].Interface().(error)
			}
		}
		return out[0].Interface(), nil
	}

	// 队列
	var out []reflect.Value
	pos := 0
	for _, key := range c.queue {
		in := []reflect.Value{}
		fn := p.m[key]
		end := pos + len(fn.args) - len(out)

		for _, arg := range out {
			in = append(in, proto.ValueOf(arg))
		}

		for _, arg := range args[pos:end] {
			in = append(in, proto.ValueOf(arg))
		}

		pos = end

		out = fn.apply.Call(in)
		end = len(out) - 1
		if end < 0 {
			return nil, toFail(like)
		}
		switch fn.ify {
		case "bool":
			if out[end].Kind() != reflect.Bool || !out[end].Bool() {
				return nil, toFail(like)
			}
			out = out[:end]
		case "error":
			if !out[end].IsNil() {
				return nil, out[end].Interface().(error)
			}
			out = out[:end]
		}
	}
	return out[0].Interface(), nil
}