Beispiel #1
1
func (cfg *PageHeader) SetValue(key string, value string, s *reflect.Value) {
	// put unknown fields into a map
	if _, ok := s.Type().FieldByName(key); !ok {
		cfg.Other[key] = strings.TrimSpace(value)
		return
	}

	// Set value
	f := s.FieldByName(key)
	switch f.Interface().(type) {
	default:
		errhandle(fmt.Errorf("Unknown type of field %s", key))
	case string:
		f.SetString(value)
	case []string:
		values := strings.Split(value, ",")
		for i, v := range values {
			values[i] = strings.TrimSpace(v)
		}
		f.Set(reflect.ValueOf(values))
	case time.Time:
		var t time.Time
		var err error
		for _, fmt := range DATEFORMATS {
			t, err = time.Parse(fmt, value)
			if err == nil {
				break
			}
		}
		errhandle(err)
		f.Set(reflect.ValueOf(t))
	}
}
Beispiel #2
0
Datei: scan.go Projekt: rjp/crud
func (scan *Scan) ScanToStruct(rows *sql.Rows, record reflect.Value) error {
	columns, err := rows.Columns()
	if err != nil {
		return err
	}

	values := make([]interface{}, len(columns))

	for i, column := range columns {
		var field reflect.Value

		fieldName := scan.SQLColumnDict[column]

		if scan.ToPointers {
			field = record.Elem().FieldByName(fieldName)
		} else {
			field = record.FieldByName(fieldName)
		}

		if field.IsValid() {
			values[i] = field.Addr().Interface()
		} else {
			values[i] = &values[i]
		}
	}

	return rows.Scan(values...)
}
Beispiel #3
0
func (q *Query) findPopulatePath(path string) {
	parts := strings.Split(path, ".")
	resultVal := reflect.ValueOf(q.parentStruct).Elem()

	var refVal reflect.Value
	partsLen := len(parts)
	for i := 0; i < partsLen; i++ {
		elem := parts[i]
		if i == 0 {
			refVal = resultVal.FieldByName(elem)
			structTag, _ := resultVal.Type().FieldByName(elem)
			q.popSchema = structTag.Tag.Get(q.z.modelTag)
		} else if i == partsLen-1 {
			structTag, _ := refVal.Type().FieldByName(elem)
			q.popSchema = structTag.Tag.Get(q.z.modelTag)
			refVal = refVal.FieldByName(elem)
		} else {
			//refVal = handleSlice(refVal, elem, path)
			refVal = refVal.FieldByName(elem)
		}

		if !refVal.IsValid() {
			panic("field `" + elem + "` not found in populate path `" + path + "`")
		}
	}

	if refVal.Kind() == reflect.Slice {
		q.isSlice = true
	}
	q.populateField = refVal.Interface()
}
Beispiel #4
0
func getFields(v reflect.Value, tagName string) []*Field {
	if v.Kind() == reflect.Ptr {
		v = v.Elem()
	}

	t := v.Type()

	var fields []*Field

	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)

		if tag := field.Tag.Get(tagName); tag == "-" {
			continue
		}

		f := &Field{
			field: field,
			value: v.FieldByName(field.Name),
		}

		fields = append(fields, f)

	}

	return fields
}
Beispiel #5
0
func (j *JSONPath) findFieldInValue(value *reflect.Value, node *FieldNode) (reflect.Value, error) {
	t := value.Type()
	var inlineValue *reflect.Value
	for ix := 0; ix < t.NumField(); ix++ {
		f := t.Field(ix)
		jsonTag := f.Tag.Get("json")
		parts := strings.Split(jsonTag, ",")
		if len(parts) == 0 {
			continue
		}
		if parts[0] == node.Value {
			return value.Field(ix), nil
		}
		if len(parts[0]) == 0 {
			val := value.Field(ix)
			inlineValue = &val
		}
	}
	if inlineValue != nil {
		if inlineValue.Kind() == reflect.Struct {
			// handle 'inline'
			match, err := j.findFieldInValue(inlineValue, node)
			if err != nil {
				return reflect.Value{}, err
			}
			if match.IsValid() {
				return match, nil
			}
		}
	}
	return value.FieldByName(node.Value), nil
}
Beispiel #6
0
// unmarshalSettings sets for all its settings the relating field of v.
func unmarshalSettings(settings SettingList, v reflect.Value) {
	for _, s := range settings {
		field := v.FieldByName(upperFirst(s.Name()))
		if !field.CanSet() {
			continue
		}

		switch s.Type() {
		case String:
			if field.Kind() == reflect.String {
				field.SetString(s.AsString())
			}

		case Integer:
			switch field.Kind() {
			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
				if s.AsInteger() >= 0 {
					field.SetUint(uint64(s.AsInteger()))
				}

			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
				field.SetInt(s.AsInteger())
			}

		case Real:
			if field.Kind() == reflect.Float32 || field.Kind() == reflect.Float64 {
				field.SetFloat(s.AsReal())
			}
		}
	}
}
Beispiel #7
0
func mergeStruct(out, in reflect.Value) {
	sprop := GetProperties(in.Type())
	for i := 0; i < in.NumField(); i++ {
		f := in.Type().Field(i)
		if strings.HasPrefix(f.Name, "XXX_") {
			continue
		}
		mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i])
	}

	if emIn, ok := in.Addr().Interface().(extensionsMap); ok {
		emOut := out.Addr().Interface().(extensionsMap)
		mergeExtension(emOut.ExtensionMap(), emIn.ExtensionMap())
	} else if emIn, ok := in.Addr().Interface().(extensionsBytes); ok {
		emOut := out.Addr().Interface().(extensionsBytes)
		bIn := emIn.GetExtensions()
		bOut := emOut.GetExtensions()
		*bOut = append(*bOut, *bIn...)
	}

	uf := in.FieldByName("XXX_unrecognized")
	if !uf.IsValid() {
		return
	}
	uin := uf.Bytes()
	if len(uin) > 0 {
		out.FieldByName("XXX_unrecognized").SetBytes(append([]byte(nil), uin...))
	}
}
Beispiel #8
0
// DelQuery will delete (from datastore and memcache) all entities of type src that matches q.
// src must be a pointer to a struct type.
func DelQuery(c PersistenceContext, src interface{}, q *datastore.Query) (err error) {
	var dataIds []*datastore.Key
	results := reflect.New(reflect.SliceOf(reflect.TypeOf(src).Elem()))
	dataIds, err = q.GetAll(c, results.Interface())
	if err = FilterOkErrors(err); err != nil {
		return
	}
	memcacheKeys := []string{}
	var el reflect.Value
	resultsSlice := results.Elem()
	for index, dataId := range dataIds {
		el = resultsSlice.Index(index)
		var k key.Key
		if k, err = gaekey.FromGAE(dataId); err != nil {
			return
		}
		el.FieldByName("Id").Set(reflect.ValueOf(k))
		if _, err = MemcacheKeys(c, el.Addr().Interface(), &memcacheKeys); err != nil {
			return
		}
		if err = runProcess(c, el.Addr().Interface(), BeforeDeleteName, nil); err != nil {
			return
		}
	}
	if err = datastore.DeleteMulti(c, dataIds); err != nil {
		return
	}
	for index, _ := range dataIds {
		el = resultsSlice.Index(index)
		if err = runProcess(c, el.Addr().Interface(), AfterDeleteName, nil); err != nil {
			return
		}
	}
	return memcache.Del(c, memcacheKeys...)
}
Beispiel #9
0
func setFieldDefaults(v reflect.Value, sf reflect.StructField, s reflect.Value) {
	if v.CanInterface() && reflect.DeepEqual(
		v.Interface(), reflect.Zero(v.Type()).Interface()) {
		tag := sf.Tag.Get("ebmldef")
		if tag != "" {
			switch v.Kind() {
			case reflect.Int, reflect.Int64:
				u, _ := strconv.ParseInt(tag, 10, 0)
				v.SetInt(int64(u))
			case reflect.Uint, reflect.Uint64:
				u, _ := strconv.ParseUint(tag, 10, 0)
				v.SetUint(u)
			case reflect.Float32, reflect.Float64:
				f, _ := strconv.ParseFloat(tag, 64)
				v.SetFloat(f)
			case reflect.String:
				v.SetString(tag)
			default:
				log.Panic("Unsupported default value")
			}
		}
		ltag := sf.Tag.Get("ebmldeflink")
		if ltag != "" {
			v.Set(s.FieldByName(ltag))
		}
	}
}
Beispiel #10
0
func (d *decoder) decodeStruct(src hl7.Data, dst reflect.Value) {
	typ := dst.Type()
	for i := 0; i < typ.NumField(); i++ {
		field := typ.Field(i)
		fieldName := field.Name
		fieldValue := dst.FieldByName(fieldName)

		// So just skip it.
		if !fieldValue.CanSet() {
			d.err.append(fmt.Errorf("%s.%s is not settable", typ.Name(), fieldName))
			continue
		}

		index := i
		if _, ok := src.(hl7.Segment); ok {
			index += 1
		}

		newSrc, ok := src.Index(index)
		if !ok {
			//d.err.append(fmt.Errorf("could not find src index for %s.%s", typ.Name(), fieldName))
			continue
		}

		d.decode(newSrc, fieldValue)
	}
}
Beispiel #11
0
func (e *encoder) encodeStruct(val reflect.Value) {
	fmt.Fprint(e, "<struct>")

	t := val.Type()
	for i := 0; i < t.NumField(); i++ {
		f := t.Field(i)
		v := val.FieldByName(f.Name)
		if e.isNil(v) {
			continue
		}

		fmt.Fprintf(e, "<member>")

		name := f.Tag.Get("xmlrpc")
		if name == "" {
			name = f.Name
		}
		fmt.Fprintf(e, "<name>%s</name>", name)
		e.encodeValue(v)

		fmt.Fprintf(e, "</member>")
	}

	fmt.Fprint(e, "</struct>")
}
Beispiel #12
0
func applyToStruct(obj reflect.Value, head P, mid string, tail P, ctx *Context) error {
	if mid != "*" {
		result := obj.FieldByName(mid)

		if result.Kind() == reflect.Invalid {
			result = obj.MethodByName(mid)
		}

		if result.Kind() == reflect.Invalid {
			return fmt.Errorf("no field '%s' in type '%s' at '%s'", mid, obj.Type(), head)
		}

		return apply(result, append(head, mid), tail, ctx)
	}

	typ := obj.Type()

	for i := 0; i < typ.NumField() && !ctx.stop; i++ {
		if err := applyToStruct(obj, head, typ.Field(i).Name, tail, ctx); err != nil && err != ErrMissing {
			return err
		}
	}

	return nil
}
Beispiel #13
0
func skipField(v reflect.Value, f reflect.StructField) bool {
	// no tag on the structure field
	name := f.Tag.Get("when")
	if name == "" {
		return false
	}
	// invalid field in tag
	f1 := v.FieldByName(name)
	if !f1.IsValid() {
		return false
	}
	// target field is not a string
	if f1.Type().Kind() != reflect.String {
		return false
	}

	target := f1.String()
	value := f.Tag.Get("value")

	switch f.Tag.Get("cond") {
	case "is":
		// skip when target equals value
		return (target == value)
	case "not":
		return (target != value)
	}

	return false
}
Beispiel #14
0
func setDefaults(properties []PropertyDocs, defaults reflect.Value) {
	for i := range properties {
		prop := &properties[i]
		fieldName := proptools.FieldNameForProperty(prop.Name)
		f := defaults.FieldByName(fieldName)
		if (f == reflect.Value{}) {
			panic(fmt.Errorf("property %q does not exist in %q", fieldName, defaults.Type()))
		}

		if reflect.DeepEqual(f.Interface(), reflect.Zero(f.Type()).Interface()) {
			continue
		}

		if f.Type().Kind() == reflect.Interface {
			f = f.Elem()
		}

		if f.Type().Kind() == reflect.Ptr {
			f = f.Elem()
		}

		if f.Type().Kind() == reflect.Struct {
			setDefaults(prop.Properties, f)
		} else {
			prop.Default = fmt.Sprintf("%v", f.Interface())
		}
	}
}
Beispiel #15
0
// model中类型提取其中的 idField(int 类型) 属性组成 slice 返回
func Models2Intslice(models interface{}, idField string) []int {
	if models == nil {
		return []int{}
	}

	// 类型检查
	modelsValue := reflect.ValueOf(models)
	if modelsValue.Kind() != reflect.Slice {
		return []int{}
	}

	var modelValue reflect.Value

	length := modelsValue.Len()
	ids := make([]int, 0, length)

	for i := 0; i < length; i++ {
		modelValue = reflect.Indirect(modelsValue.Index(i))
		if modelValue.Kind() != reflect.Struct {
			continue
		}

		val := modelValue.FieldByName(idField)
		if val.Kind() != reflect.Int {
			continue
		}

		ids = append(ids, int(val.Int()))
	}

	return ids
}
Beispiel #16
0
// Required a struct type
func (g *Graph) findFieldValue(parent reflect.Value, path structPath, linneage *[]reflect.Value) (reflect.Value, error) {

	*linneage = append(*linneage, parent)

	// Dereference incoming values
	if parent.Kind() == reflect.Ptr {
		parent = parent.Elem()
	}

	// Only accept structs
	if parent.Kind() != reflect.Struct {
		return parent, fmt.Errorf("Type is %s, not struct", parent.Kind().String())
	}

	// Take the first entry from the path
	stub, path := path.Shift()

	// Try to get the field
	f := parent.FieldByName(stub)

	if !f.IsValid() {
		return f, fmt.Errorf("Can't find field %s in %s", stub, parent)
	}

	// If that's the end of the path, return the value
	if path.Empty() {
		return f, nil
	}

	// Otherwise recurse
	return g.findFieldValue(f, path, linneage)
}
Beispiel #17
0
func extractCost(v reflect.Value) int64 {
	v = v.FieldByName("Cost")
	if v.Kind() != reflect.Ptr {
		return 0
	}
	v = v.Elem()
	if v.Kind() != reflect.Struct {
		return 0
	}

	extract := func(name string) int64 {
		w := v.FieldByName(name)
		if w.Kind() != reflect.Ptr {
			return 0
		}
		w = w.Elem()
		switch w.Kind() {
		case reflect.Int, reflect.Int32, reflect.Int64:
			return w.Int()
		}

		return 0
	}

	return (extract("IndexWrites") + extract("EntityWrites")) * cost.Write
}
Beispiel #18
0
func unmarshalStruct(data string, v reflect.Value) error {
	structType := v.Type()
	var name string
	for len(data) > 0 {
		typ, content, n := readElement(data)
		data = data[n:]
		if typ != ',' {
			return errors.New("tnetstring: non-string key in dictionary")
		}
		name = content
		field := v.FieldByName(name)
		if !field.IsValid() {
			for i := 0; i < structType.NumField(); i++ {
				f := structType.Field(i)
				if f.Tag.Get("tnetstring") == name {
					field = v.Field(i)
					break
				}
			}
			if !field.IsValid() {
				// skip the field
				_, _, n := readElement(data)
				data = data[n:]
				continue
			}
		}
		n, err := unmarshal(data, field)
		data = data[n:]
		if err != nil {
			return err
		}
	}
	return nil
}
Beispiel #19
0
func convertStruct(in interface{}, val reflect.Value) *ConfigError {
	dict, ok := in.(map[string]interface{})
	if !ok || len(dict) != val.NumField() {
		return &ConfigError{ErrInvalidType, ""}
	}

	for k, from := range dict {
		to := val.FieldByName(strings.ToTitle(k[:1]) + k[1:])
		if !to.IsValid() {
			return &ConfigError{ErrInvalidType, ""}
		}

		convertor := convertFuncs.get(to)
		if convertor == nil {
			return &ConfigError{ErrInvalidType, ""}
		}

		if err := convertor(from, to); err != nil {
			if len(err.Field) > 0 {
				err.Field = fmt.Sprintf("%s.%s", k, err.Field)
			} else {
				err.Field = k
			}
			return err
		}
	}

	return nil
}
Beispiel #20
0
// extractFromObjectMeta extracts pointers to metadata fields from an object
func extractFromObjectMeta(v reflect.Value, a *genericAccessor) error {
	if err := runtime.FieldPtr(v, "Namespace", &a.namespace); err != nil {
		return err
	}
	if err := runtime.FieldPtr(v, "Name", &a.name); err != nil {
		return err
	}
	if err := runtime.FieldPtr(v, "GenerateName", &a.generateName); err != nil {
		return err
	}
	if err := runtime.FieldPtr(v, "UID", &a.uid); err != nil {
		return err
	}
	if err := runtime.FieldPtr(v, "ResourceVersion", &a.resourceVersion); err != nil {
		return err
	}
	if err := runtime.FieldPtr(v, "SelfLink", &a.selfLink); err != nil {
		return err
	}
	if err := runtime.FieldPtr(v, "Labels", &a.labels); err != nil {
		return err
	}
	if err := runtime.FieldPtr(v, "Annotations", &a.annotations); err != nil {
		return err
	}
	ownerReferences := v.FieldByName("OwnerReferences")
	if !ownerReferences.IsValid() {
		return fmt.Errorf("struct %#v lacks OwnerReferences type", v)
	}
	if ownerReferences.Kind() != reflect.Slice {
		return fmt.Errorf("expect %v to be a slice", ownerReferences.Kind())
	}
	a.ownerReferences = ownerReferences.Addr()
	return nil
}
Beispiel #21
0
func encodeStruct(val reflect.Value) ([]byte, error) {
	var b bytes.Buffer

	b.WriteString("<struct>")

	t := val.Type()
	for i := 0; i < t.NumField(); i++ {
		b.WriteString("<member>")
		f := t.Field(i)

		name := f.Tag.Get("xmlrpc")
		if name == "" {
			name = f.Name
		}
		b.WriteString(fmt.Sprintf("<name>%s</name>", name))

		p, err := encodeValue(val.FieldByName(f.Name))
		if err != nil {
			return nil, err
		}
		b.Write(p)

		b.WriteString("</member>")
	}

	b.WriteString("</struct>")

	return b.Bytes(), nil
}
Beispiel #22
0
func copyType(rv reflect.Value, name string) (reflect.Value, error) {
	field := rv.FieldByName(name)
	if !field.IsValid() {
		return rv, errors.New("Internal error: " + rv.Type().String() + " missing field " + name)
	}
	return reflect.New(field.Type()), nil
}
Beispiel #23
0
func addFields(m *Model, t reflect.Type, v reflect.Value) {
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)
		sqlTag := field.Tag.Get("sql")
		if sqlTag == "-" {
			continue
		}
		if field.Anonymous && field.Type.Kind() == reflect.Struct {
			addFields(m, field.Type, v.Field(i))
			continue
		}
		parsedSqlTags := parseTags(sqlTag)
		rawValidateTag := field.Tag.Get("validate")
		parsedValidateTags := make(map[string]string)
		if len(rawValidateTag) > 0 {
			if rawValidateTag[:1] == "^" {
				parsedValidateTags["regexp"] = rawValidateTag
			} else {
				parsedValidateTags = parseTags(rawValidateTag)
			}
		}
		fd := &ModelField{
			Name:         toSnake(field.Name),
			Value:        v.FieldByName(field.Name).Interface(),
			SqlTags:      parsedSqlTags,
			ValidateTags: parsedValidateTags,
			RawTag:       field.Tag,
		}
		if fd.PrimaryKey() {
			m.Pk = fd
		}
		m.Fields = append(m.Fields, fd)
	}
}
Beispiel #24
0
// isSameUnknownStruct returns true if the two struct values are the same length
// and have the same contents as defined by IsSame. This function explicitly
// ignores the declared type of the struct.
func isSameStruct(x, y reflect.Value) bool {

	sx, okx := x.Interface().(StringConvertable)
	sy, oky := x.Interface().(StringConvertable)

	if okx && oky {
		//log.Println("Stringable", x, y)
		return sx.String() == sy.String()
	}

	numFields := x.NumField()

	if numFields != y.NumField() {
		return false
	}

	typeX := x.Type()

	for i := 0; i < numFields; i++ {
		path := []int{i}
		vx := x.FieldByIndex(path)
		vy := y.FieldByName(typeX.Field(i).Name)
		if vx.CanInterface() && vy.CanInterface() {
			if !IsSame(vx.Interface(), vy.Interface()) {
				return false
			}
		}
	}

	return true
}
Beispiel #25
0
func Validate(validation *revel.Validation, obj interface{}) {
	// Get reflection data to parse validation tag data
	var v reflect.Value = reflect.Indirect(reflect.ValueOf(obj))

	// We only want to validate structs and their tagged fields
	if v.Kind() != reflect.Struct {
		panic(fmt.Sprintf("Object is not a struct. Actual kind is: %s", v.Kind()))
	}

	// Go through each field in the struct and check for the
	// validation tag.  Apply appropriate revel check as needed.
	t := v.Type()
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)
		fieldId := fmt.Sprintf("%s.%s", t.Name(), field.Name)
		var fieldValidators []revel.Validator
		fieldValidators, ok := validationCache[fieldId]
		if tag := field.Tag.Get(TagName); !ok && len(tag) > 0 {
			fieldValidators = parseTag(tag)
			validationCache[fieldId] = fieldValidators
		} else if !ok {
			fieldValidators = nil
			validationCache[fieldId] = nil
		}
		if len(fieldValidators) > 0 {
			validation.Check(v.FieldByName(field.Name).Interface(), fieldValidators...).Key(fieldId)
		}
	}
}
Beispiel #26
0
// Search for a field named 'ID' in the provided struct
// - The 'ID' field must be of type Int | String, any other type
//   results in an error
func reflectKey(val reflect.Value) (*Key, error) {

	if val.Kind() == reflect.Ptr && val.IsNil() {
		return nil, fmt.Errorf("Key: <nil> pointer of type %s", val.String())
	}

	if val.Kind() == reflect.Ptr {
		val = Indirect(val)
	}

	// TODO: for static-only states (meaning no mutability)
	//       this might be too limiting.
	if val.Kind() != reflect.Struct {
		return nil, errors.New("Key: only structs can have a Key")
	}

	id_field := val.FieldByName("ID")

	if !id_field.IsValid() {
		return nil, fmt.Errorf("%s does not have field with name = 'ID'", val.Type().String())
	}

	switch id_field.Kind() {
	case reflect.String:
		return NewStringKey(id_field.String())
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return NewIntKey(int(id_field.Int()))
	default:
		return nil, fmt.Errorf("Field 'ID' is of invalid type: %v\n", id_field.Kind())
	}
}
Beispiel #27
0
// scan the value by fields, and set to v
func rawScanStruct(v reflect.Value, fields []string, scanner rowScaner) (err error) {
	if v.IsNil() {
		e := fmt.Sprintf("struct can not be nil, but got %#v", v.Interface())
		return errors.New(e)
	}
	dest := make([]interface{}, len(fields))
	for v.Kind() == reflect.Ptr {
		v = v.Elem()
	}

	// Loop over column names and find field in s to bind to
	// based on column name. all returned columns must match
	// a field in the s struct
	for x, fieldName := range fields {
		f := v.FieldByName(fieldName)
		if f == zeroVal {
			e := fmt.Sprintf("Scanner: No field %s in type %s",
				fieldName, v.Type())
			return errors.New(e)
		} else {
			dest[x] = f.Addr().Interface()
		}
	}

	err = scanner.Scan(dest...)
	return
}
Beispiel #28
0
func lookup(v reflect.Value, s string) reflect.Value {
	var ret reflect.Value
	v = reflect.Indirect(v)
	switch v.Kind() {
	case reflect.Array, reflect.Slice:
		if idx, err := strconv.Atoi(s); err == nil {
			ret = v.Index(idx)
		}
	case reflect.Map:
		keyt := v.Type().Key()
		switch keyt.Kind() {
		case reflect.String:
			ret = v.MapIndex(reflect.ValueOf(s))
		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
			if idx, err := strconv.ParseInt(s, 10, 64); err == nil {
				idxVal := reflect.New(keyt).Elem()
				idxVal.SetInt(idx)
				ret = v.MapIndex(idxVal)
			}
		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
			if idx, err := strconv.ParseUint(s, 10, 64); err == nil {
				idxVal := reflect.New(keyt).Elem()
				idxVal.SetUint(idx)
				ret = v.MapIndex(idxVal)
			}
		}
	case reflect.Struct:
		ret = v.FieldByName(s)
	}
	// TODO: Find a way to look up methods by name
	return ret
}
Beispiel #29
0
// validateStruct will validate the struct value's fields. If the structure has
// nested types those types will be validated also.
func (v *validator) validateStruct(value reflect.Value, path string) {
	prefix := "."
	if path == "" {
		prefix = ""
	}

	for i := 0; i < value.Type().NumField(); i++ {
		f := value.Type().Field(i)
		if strings.ToLower(f.Name[0:1]) == f.Name[0:1] {
			continue
		}
		fvalue := value.FieldByName(f.Name)

		notset := false
		if f.Tag.Get("required") != "" {
			switch fvalue.Kind() {
			case reflect.Ptr, reflect.Slice, reflect.Map:
				if fvalue.IsNil() {
					notset = true
				}
			default:
				if !fvalue.IsValid() {
					notset = true
				}
			}
		}

		if notset {
			msg := "missing required parameter: " + path + prefix + f.Name
			v.errors = append(v.errors, msg)
		} else {
			v.validateAny(fvalue, path+prefix+f.Name)
		}
	}
}
Beispiel #30
0
func mergeStruct(out, in reflect.Value) {
	sprop := GetProperties(in.Type())
	for i := 0; i < in.NumField(); i++ {
		f := in.Type().Field(i)
		if strings.HasPrefix(f.Name, "XXX_") {
			continue
		}
		mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i])
	}

	if emIn, ok := extendable(in.Addr().Interface()); ok {
		emOut, _ := extendable(out.Addr().Interface())
		mIn, muIn := emIn.extensionsRead()
		if mIn != nil {
			mOut := emOut.extensionsWrite()
			muIn.Lock()
			mergeExtension(mOut, mIn)
			muIn.Unlock()
		}
	}

	uf := in.FieldByName("XXX_unrecognized")
	if !uf.IsValid() {
		return
	}
	uin := uf.Bytes()
	if len(uin) > 0 {
		out.FieldByName("XXX_unrecognized").SetBytes(append([]byte(nil), uin...))
	}
}