Пример #1
0
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
}
Пример #2
0
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
	}

}
Пример #3
0
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
}
Пример #4
0
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())
}
Пример #5
0
// 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
}
Пример #6
0
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
}
Пример #7
0
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
}
Пример #8
0
// 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
}
Пример #9
0
// 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
}
Пример #10
0
// 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
}