Example #1
2
// sf is the recursive function used to build the structure neeeded by SelectFields
func sf(in interface{}, c echo.Context) (interface{}, error) {

	in = reflect.Indirect(reflect.ValueOf(in)).Interface()
	Type := reflect.TypeOf(in)

	switch Type.Kind() {
	case reflect.Struct:
		ret := make(map[string]interface{})
		value := reflect.ValueOf(in)
		if fieldString := c.QueryParam("fields"); fieldString != "" {
			fields := strings.Split(fieldString, ",")
			for _, field := range fields {
				fieldName := utils.UpperFirst(field)
				if structField, ok := Type.FieldByName(fieldName); ok {
					jsonTag := structField.Tag.Get("json")
					if jsonTag != "-" && jsonTag != "" {
						ret[strings.Split(jsonTag, ",")[0]] = value.FieldByName(fieldName).Interface()
					}
				} else {
					// Else check if json field name is different from struct field name (with first letter in uppercase)
					// this is the user expected behaviour, but we prefer the above approach to speed up the process
					var found bool
					for i := 0; i < Type.NumField(); i++ {
						jsonTag := Type.Field(i).Tag.Get("json")
						if strings.Split(jsonTag, ",")[0] == field {
							ret[field] = value.Field(i).Interface()
							found = true
							break
						}
					}
					if !found {
						return nil, fmt.Errorf("Field %s does not exists", field)
					}
				}
			}
		} else {
			for i := 0; i < Type.NumField(); i++ {
				jsonTag := Type.Field(i).Tag.Get("json")
				if jsonTag != "-" && jsonTag != "" {
					ret[strings.Split(jsonTag, ",")[0]] = value.Field(i).Interface()
				}
			}
		}
		return &ret, nil

	case reflect.Slice:
		value := reflect.ValueOf(in)
		ret := make([]interface{}, value.Len())
		for i := 0; i < value.Len(); i++ {
			if m, e := sf(value.Index(i).Elem().Interface(), c); e == nil {
				ret[i] = m
			} else {
				return nil, fmt.Errorf(`Error "%s" on field number %d`, e.Error(), i)
			}
		}
		return &ret, nil
	}

	return nil, errors.New("input parameter is not a struct or a slice of struct")
}
Example #2
0
func TestUpperFirst(t *testing.T) {
	if utils.UpperFirst("ciao") != "Ciao" {
		t.Errorf("UpperFirst does not work")
	}
}