func validateSelection(field *structs.Field, selection string) error { selectionSet := strings.Split(selection, "|") switch field.Kind() { case reflect.Int: i := field.Value().(int) s := strconv.Itoa(i) for _, selection := range selectionSet { if s == selection { return nil } } return fmt.Errorf("validate: Field %s value %s, not in selection %s.", field.Name(), s, selection) case reflect.String: s := field.Value().(string) for _, selection := range selectionSet { if s == selection { return nil } } return fmt.Errorf("validate: Field %s value %s, not in selection %s.", field.Name(), s, selection) default: return nil } return nil }
func parseValue(field *structs.Field, val string) (interface{}, error) { switch field.Kind() { case reflect.Int: v, err := strconv.Atoi(val) if err != nil { return nil, err } return v, nil case reflect.Float64: v, err := strconv.ParseFloat(val, 64) if err != nil { return nil, err } return v, nil case reflect.Bool: v, err := strconv.ParseBool(val) if err != nil { return nil, err } return v, nil default: fieldVal := field.Value() if _, casted := fieldVal.(bson.ObjectId); casted { if bson.IsObjectIdHex(val) { return bson.ObjectIdHex(val), nil } else { return nil, fmt.Errorf("should be bson.ObjectId hex") } } if _, casted := (fieldVal).(time.Time); casted { v := &time.Time{} return v, v.UnmarshalText([]byte(val)) } if convertable, casted := fieldVal.(Converter); casted { converted, err := convertable.Convert(val) if err != nil { return nil, err } if enum, casted := fieldVal.(Enumer); casted { enumValues := enum.Enum() for _, eV := range enumValues { if eV == converted { return converted, nil } } return nil, fmt.Errorf("should be one of %v", enumValues) } return converted, nil } return val, nil } }
func validateString(field *structs.Field, regex string) error { switch field.Kind() { case reflect.String: i := field.Value().(string) matched, err := regexp.MatchString(regex, i) if err == nil && !matched { return fmt.Errorf("validate: Field %s value %s, regex %s not matched.", field.Name(), i, regex) } } return nil }
func getBytes(f *structs.Field) ([]byte, error) { var b *bytes.Buffer switch f.Kind() { case reflect.Slice: if reflect.ValueOf(f.Value()).Type().Elem().Kind() == reflect.Uint8 { // []byte return (f.Value()).([]byte), nil } case reflect.String: return []byte((f.Value()).(string)), nil case reflect.Bool: return boolconv.NewBool((f.Value()).(bool)).Bytes(), nil case reflect.Int8, reflect.Uint8: b = bytes.NewBuffer(make([]byte, 0, 2)) case reflect.Int16, reflect.Uint16: b = bytes.NewBuffer(make([]byte, 0, binary.MaxVarintLen16)) case reflect.Int32, reflect.Uint32: b = bytes.NewBuffer(make([]byte, 0, binary.MaxVarintLen32)) case reflect.Int64, reflect.Uint64, reflect.Int, reflect.Uint, reflect.Float32, reflect.Float64: b = bytes.NewBuffer(make([]byte, 0, binary.MaxVarintLen64)) } if b != nil { i := f.Value() if f.Kind() == reflect.Int { i = int64(i.(int)) } if f.Kind() == reflect.Uint { i = uint64(i.(uint)) } err := binary.Write(b, binary.BigEndian, i) return b.Bytes(), err } return nil, fmt.Errorf("cloth: unsupported type. %v", f.Kind()) }
// fieldSet sets field value from the given string value. It converts the // string value in a sane way and is usefulf or environment variables or flags // which are by nature in string types. func fieldSet(field *structs.Field, v string) error { // TODO: add support for other types switch field.Kind() { case reflect.Bool: val, err := strconv.ParseBool(v) if err != nil { return err } if err := field.Set(val); err != nil { return err } case reflect.Int: i, err := strconv.Atoi(v) if err != nil { return err } if err := field.Set(i); err != nil { return err } case reflect.String: field.Set(v) case reflect.Slice: // TODO add other typed slice support if _, ok := field.Value().([]string); !ok { return errors.New("can't set on non string slices") } if err := field.Set(strings.Split(v, ",")); err != nil { return err } case reflect.Float64: f, err := strconv.ParseFloat(v, 64) if err != nil { return err } if err := field.Set(f); err != nil { return err } default: return fmt.Errorf("multiconfig: not supported type: %s", field.Kind()) } return nil }
func validateLength(field *structs.Field, minlenStr string, maxlenStr string) error { switch field.Kind() { case reflect.String: i := field.Value().(string) l := len(i) min, minErr := strconv.Atoi(minlenStr) max, maxErr := strconv.Atoi(maxlenStr) if (minErr == nil && l < min) || (maxErr == nil && l > max) { return fmt.Errorf("validate: Field %s value %s, length limit: [%s, %s]", field.Name(), i, minlenStr, maxlenStr) } default: return nil } return nil }
func validateRange(field *structs.Field, minStr string, maxStr string) error { switch field.Kind() { case reflect.Int: i := field.Value().(int) min, minErr := strconv.Atoi(minStr) max, maxErr := strconv.Atoi(maxStr) if (minErr == nil && i < min) || (maxErr == nil && i > max) { return fmt.Errorf("validate: Field %s value %d, want: [%s, %s]", field.Name(), i, minStr, maxStr) } case reflect.Float64: i := field.Value().(float64) min, minErr := strconv.ParseFloat(minStr, 64) max, maxErr := strconv.ParseFloat(maxStr, 64) if (minErr == nil && i < min) || (maxErr == nil && i > max) { return fmt.Errorf("validate: Field %s value %f, want: [%s, %s]", field.Name(), i, minStr, maxStr) } case reflect.Int64: switch field.Value().(type) { case int64: i := field.Value().(int64) min, minErr := strconv.ParseInt(minStr, 10, 64) max, maxErr := strconv.ParseInt(maxStr, 10, 64) if (minErr == nil && i < min) || (maxErr == nil && i > max) { return fmt.Errorf("validate: Field %s value %d, want: [%s, %s]", field.Name(), i, minStr, maxStr) } default: return nil } default: return nil } return nil }
// fieldSet sets field value from the given string value. It converts the // string value in a sane way and is usefulf or environment variables or flags // which are by nature in string types. func fieldSet(field *structs.Field, v string) error { // TODO: add support for other types switch field.Kind() { case reflect.Bool: val, err := strconv.ParseBool(v) if err != nil { return err } if err := field.Set(val); err != nil { return err } case reflect.Int: i, err := strconv.Atoi(v) if err != nil { return err } if field.RawValue.Type().Name() != "int" { // We're probably dealing with an enum type field.RawValue.SetInt(int64(i)) return nil } if err := field.Set(i); err != nil { return err } case reflect.String: if field.RawValue.Type().Name() != "string" { // We're probably dealing with an enum type field.RawValue.SetString(v) return nil } if err := field.Set(v); err != nil { return err } case reflect.Slice: switch t := field.Value().(type) { case []string: if err := field.Set(strings.Split(v, ",")); err != nil { return err } case []int: var list []int for _, in := range strings.Split(v, ",") { i, err := strconv.Atoi(in) if err != nil { return err } list = append(list, i) } if err := field.Set(list); err != nil { return err } default: return fmt.Errorf("multiconfig: field '%s' of type slice is unsupported: %s (%T)", field.Name(), field.Kind(), t) } case reflect.Float64: f, err := strconv.ParseFloat(v, 64) if err != nil { return err } if err := field.Set(f); err != nil { return err } case reflect.Int64: switch t := field.Value().(type) { case time.Duration: d, err := time.ParseDuration(v) if err != nil { return err } if err := field.Set(d); err != nil { return err } case int64: p, err := strconv.ParseInt(v, 10, 0) if err != nil { return err } if err := field.Set(p); err != nil { return err } default: return fmt.Errorf("multiconfig: field '%s' of type int64 is unsupported: %s (%T)", field.Name(), field.Kind(), t) } default: return fmt.Errorf("multiconfig: field '%s' has unsupported type: %s", field.Name(), field.Kind()) } return nil }
// fieldSet sets field value from the given string value. It converts the // string value in a sane way and is usefulf or environment variables or flags // which are by nature in string types. func fieldSet(field *structs.Field, v string) error { switch field.Kind() { case reflect.Bool: val, err := strconv.ParseBool(v) if err != nil { return err } if err := field.Set(val); err != nil { return err } case reflect.Int: i, err := strconv.Atoi(v) if err != nil { return err } if err := field.Set(i); err != nil { return err } case reflect.String: if err := field.Set(v); err != nil { return err } case reflect.Map: switch t := field.Value().(type) { case map[string]int: si := make(map[string]int) if err := json.Unmarshal([]byte(v), &si); err != nil { return err } if err := field.Set(si); err != nil { return err } case map[string]string: ss := make(map[string]string) if err := json.Unmarshal([]byte(v), &ss); err != nil { return err } if err := field.Set(ss); err != nil { return err } default: return fmt.Errorf("config: field '%s' of type map is unsupported: %s (%T)", field.Name(), field.Kind(), t) } case reflect.Slice: switch t := field.Value().(type) { case []string: if err := field.Set(strings.Split(v, ",")); err != nil { return err } case []int: var list []int for _, in := range strings.Split(v, ",") { i, err := strconv.Atoi(in) if err != nil { return err } list = append(list, i) } if err := field.Set(list); err != nil { return err } case []int64: var list []int64 for _, in := range strings.Split(v, ",") { i, err := strconv.ParseInt(in, 10, 64) if err != nil { return err } list = append(list, i) } if err := field.Set(list); err != nil { return err } case []float64: var list []float64 for _, in := range strings.Split(v, ",") { i, err := strconv.ParseFloat(in, 64) if err != nil { return err } list = append(list, i) } if err := field.Set(list); err != nil { return err } default: return fmt.Errorf("config: field '%s' of type slice is unsupported: %s (%T)", field.Name(), field.Kind(), t) } case reflect.Float64: f, err := strconv.ParseFloat(v, 64) if err != nil { return err } if err := field.Set(f); err != nil { return err } case reflect.Int64: switch t := field.Value().(type) { case time.Duration: d, err := time.ParseDuration(v) if err != nil { return err } if err := field.Set(d); err != nil { return err } case int64: p, err := strconv.ParseInt(v, 10, 64) if err != nil { return err } if err := field.Set(p); err != nil { return err } default: return fmt.Errorf("config: field '%s' of type int64 is unsupported: %s (%T)", field.Name(), field.Kind(), t) } default: return fmt.Errorf("config: field '%s' has unsupported type: %s", field.Name(), field.Kind()) } return nil }
// fieldSet sets field value from the given string value. It converts the // string value in a sane way and is usefulf or environment variables or flags // which are by nature in string types. func fieldSet(field *structs.Field, v string) error { switch f := field.Value().(type) { case flag.Value: if v := reflect.ValueOf(field.Value()); v.IsNil() { typ := v.Type() if typ.Kind() == reflect.Ptr { typ = typ.Elem() } if err := field.Set(reflect.New(typ).Interface()); err != nil { return err } f = field.Value().(flag.Value) } return f.Set(v) } // TODO: add support for other types switch field.Kind() { case reflect.Bool: val, err := strconv.ParseBool(v) if err != nil { return err } if err := field.Set(val); err != nil { return err } case reflect.Int: i, err := strconv.Atoi(v) if err != nil { return err } if err := field.Set(i); err != nil { return err } case reflect.String: if err := field.Set(v); err != nil { return err } case reflect.Slice: switch t := field.Value().(type) { case []string: if err := field.Set(strings.Split(v, ",")); err != nil { return err } case []int: var list []int for _, in := range strings.Split(v, ",") { i, err := strconv.Atoi(in) if err != nil { return err } list = append(list, i) } if err := field.Set(list); err != nil { return err } default: return fmt.Errorf("multiconfig: field '%s' of type slice is unsupported: %s (%T)", field.Name(), field.Kind(), t) } case reflect.Float64: f, err := strconv.ParseFloat(v, 64) if err != nil { return err } if err := field.Set(f); err != nil { return err } case reflect.Int64: switch t := field.Value().(type) { case time.Duration: d, err := time.ParseDuration(v) if err != nil { return err } if err := field.Set(d); err != nil { return err } case int64: p, err := strconv.ParseInt(v, 10, 0) if err != nil { return err } if err := field.Set(p); err != nil { return err } default: return fmt.Errorf("multiconfig: field '%s' of type int64 is unsupported: %s (%T)", field.Name(), field.Kind(), t) } default: return fmt.Errorf("multiconfig: field '%s' has unsupported type: %s", field.Name(), field.Kind()) } return nil }