예제 #1
0
파일: value_test.go 프로젝트: sdming/kiss
func testFieldsValue(t *testing.T, v reflect.Value, fields []string, fn func(v gotype.Value) bool) {
	for _, field := range fields {
		fv := v.FieldByName(field)
		k := gotype.Value(fv)
		if ok := fn(k); !ok {
			t.Errorf("field %s testing fail - %#v ", field, fn)
		}
	}
}
예제 #2
0
파일: kson.go 프로젝트: samuelyao314/mygo
func (n *Node) set(v reflect.Value) {

	// if !v.CanSet() || !v.IsValid() {
	// 	return
	// }

	// fmt.Println("set==", nameOfNodeType(n.Type), v.Type(), v.Kind())
	// fmt.Println(n.Dump())

	kind := v.Kind()
	switch {
	case gotype.IsSimple(kind):
		if n.Literal != "" {
			gotype.Value(v).Parse(n.Literal)
		}
	case kind == reflect.Invalid || kind == reflect.Uintptr || kind == reflect.UnsafePointer || kind == reflect.Func || kind == reflect.Chan || kind == reflect.Complex64 || kind == reflect.Complex128:
		//TODO: unsupport
	case kind == reflect.Array:
		n.setArray(v)
	case kind == reflect.Slice:
		n.setArray(v)
	case kind == reflect.Map:
		n.setMap(v)
	case kind == reflect.Struct:
		n.setObject(v)
	case kind == reflect.Interface:
		if n.Type == NodeLiteral {
			gotype.Value(v).Parse(n.Literal)
		}
	case kind == reflect.Ptr:
		if v.IsNil() && v.CanSet() {
			v.Set(reflect.New(v.Type().Elem()))
		}
		n.set(v.Elem())
	default:
		//TODO:
	}
}
예제 #3
0
파일: route.go 프로젝트: jango2015/wk
// Bind
func (binder *structBinder) Bind(ctx *HttpContext) ([]reflect.Value, error) {
	numIn := binder.method.NumIn
	args := make([]reflect.Value, numIn, numIn)

	for i := 0; i < numIn; i++ {
		in := binder.method.In[i]
		args[i] = reflect.Zero(in)

		if in.Kind() == reflect.Struct {
			args[i] = reflect.New(in).Elem()
		} else if in.Kind() == reflect.Ptr && in.Elem().Kind() == reflect.Struct {
			args[i] = reflect.New(in.Elem())
		} else {
			continue
		}

		uType := gotype.UnderlyingType(in)
		uValue := gotype.Underlying(args[i])
		filedNum := uType.NumField()

		for f := 0; f < filedNum; f++ {
			field := uType.Field(f)
			fieldValue := uValue.Field(f)
			fieldType := field.Type

			if !fieldValue.CanSet() {
				continue
			}

			fieldKind := fieldType.Kind()
			name := strings.ToLower(field.Name)

			str, ok := ctx.RouteData[name]
			if !ok {
				str = ctx.Request.FormValue(name)
			}
			if str == "" {
				continue
			}

			if gotype.IsSimple(fieldKind) {
				gotype.Value(fieldValue).Parse(str)
			} else {
				//TODO
			}
		}
	}

	return args, nil
}
예제 #4
0
파일: kson.go 프로젝트: samuelyao314/mygo
func (n *Node) setArray(v reflect.Value) {

	kind := v.Kind()
	if n.Type != NodeList || (kind != reflect.Slice && kind != reflect.Array) {
		return
	}

	typ := v.Type()
	if n.List == nil {
		if v.CanSet() {
			v.Set(reflect.Zero(typ))
		}
		return
	}

	l := len(n.List)
	if kind == reflect.Slice {
		if v.CanSet() {
			v.Set(reflect.MakeSlice(v.Type(), l, l))
		} else {
			return
		}
	}

	vl := v.Len()
	elemType := typ.Elem()
	elemKind := elemType.Kind()
	simple := gotype.IsSimple(elemKind)

	for i, x := range n.List {
		if i < vl { // capacity of array maybe less of i
			if simple && x.Type == NodeLiteral {
				gotype.Value(v.Index(i)).Parse(x.Literal)
			} else {
				x.set(v.Index(i))
			}
		}
	}

	if kind == reflect.Array && l < vl {
		for i := l; i < vl; i++ {
			z := reflect.Zero(v.Type().Elem()) //reset
			v.Index(i).Set(z)
		}
	}
}
예제 #5
0
파일: kson.go 프로젝트: samuelyao314/mygo
func (n *Node) setObject(v reflect.Value) {

	kind := v.Kind()
	if n.Type != NodeHash || kind != reflect.Struct {
		return
	}

	typ := v.Type()
	if n.Hash == nil {
		if v.CanSet() {
			v.Set(reflect.Zero(typ))
			return
		}
	}

	numFiled := typ.NumField()
	for i := 0; i < numFiled; i++ {
		field := typ.Field(i)
		if field.PkgPath != "" {
			continue
		}

		name := field.Name
		filedNode, ok := n.Child(name)
		if !ok {
			filedNode, ok = n.ChildFold(name)
		}
		if !ok {
			continue
		}

		fv := v.Field(i)
		if !fv.CanSet() {
			continue
		}

		kind := field.Type.Kind()
		if filedNode.Type == NodeLiteral && gotype.IsSimple(kind) {
			gotype.Value(fv).Parse(filedNode.Literal)
		} else {
			filedNode.set(fv)
		}
	}

}
예제 #6
0
파일: kiss.go 프로젝트: samuelyao314/mygo
// copy value from src to dest, the dest must be struct
func ExtdStruct(dest reflect.Value, src Getter) {
	if !dest.IsValid() || dest.Kind() != reflect.Struct || src == nil {
		return
	}

	typ := dest.Type()
	num := typ.NumField()
	for i := 0; i < num; i++ {
		field := typ.Field(i)
		x, ok := src.Get(field.Name)
		if !ok || !x.IsValid() {
			continue
		}

		v := gotype.Value(dest.Field(i))
		v.Set(x)
	}

}
예제 #7
0
// TODO: adjust indent algorithm
func (e *encoder) visitReflectValue(v reflect.Value) {

	if !v.IsValid() {
		e.WriteString("")
	}

	//v = gotype.Underlying(v)
	kind := v.Kind()
	switch kind {
	case reflect.Bool,
		reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
		reflect.Float32, reflect.Float64:
		e.WriteString(gotype.Value(v).Format())
	case reflect.String:
		s := v.String()
		if b, quote := stringNeedQuote(s); b {
			e.WriteString(quote)
			e.WriteString(s)
			e.WriteString(quote)
			//e.WriteString("\n")
		} else {
			e.WriteString(s)
		}
	case reflect.Struct:
		//fmt.Fprintln(e, "{")
		e.WriteByte('{')
		e.WriteByte('\n')
		e.indentInner()

		typ := v.Type()
		count := typ.NumField()
		for i := 0; i < count; i++ {
			f := typ.Field(i)

			if f.PkgPath != "" {
				continue
			}

			e.indent()
			//fmt.Fprint(e, f.Name)
			e.WriteString(f.Name)
			//fmt.Fprint(e, ":")
			e.WriteByte(':')
			e.visitReflectValue(v.Field(i))
			//fmt.Fprintln(e, "")
			e.WriteByte('\n')
		}

		e.indentOuter()
		e.indent()
		//fmt.Fprintln(e, "}")
		e.WriteByte('}')
		e.WriteByte('\n')
	case reflect.Map:
		if !gotype.IsSimple(v.Type().Key().Kind()) {
			return
		}

		if v.IsNil() {
			//fmt.Fprint(e, "") //fmt.Fprint(e, "null")
			e.WriteByte(' ')
			break
		}

		//fmt.Fprintln(e, "{")
		e.WriteByte('{')
		e.WriteByte('\n')
		e.indentInner()

		keys := v.MapKeys()
		for _, k := range keys {
			e.indent()
			//fmt.Fprint(e, k)
			e.WriteString(k.String())
			//fmt.Fprint(e, ":")
			e.WriteByte(':')
			e.visitReflectValue(v.MapIndex(k))
			//fmt.Fprintln(e, "")
			e.WriteByte('\n')
		}
		e.indentOuter()
		e.indent()
		//fmt.Fprintln(e, "}")
		e.WriteByte('}')
		e.WriteByte('\n')
	case reflect.Slice:

		if v.IsNil() {
			//fmt.Fprint(e, "") //fmt.Fprint(e, "null")
			e.WriteByte(' ')
			break
		}
		e.visitArray(v)
	case reflect.Array:
		e.visitArray(v)
	case reflect.Interface, reflect.Ptr:
		if v.IsNil() || !v.IsValid() {
			//fmt.Fprint(e, "") //fmt.Fprint(e, "null")
			e.WriteByte(' ')
			return
		}
		e.visitReflectValue(v.Elem())
	default:
		fmt.Fprint(e, v.Interface())
		//return errors.New("Unsupported type " + v.Type().String())
	}
	return
}