reflect API

reflect

package

API reference for the reflect package.

F
function

Bind

Bind value converts a string to a reflect.Value based on its kind.

It supports basic types (string, int, uint, float, bool, duration) and slices of strings.

Parameters

value
string

Returns

error
pkg/reflect/reflect.go:19-69
func Bind(val reflect.Value, value string) error

{
	if !val.CanSet() {
		return fmt.Errorf("reflect: cannot set value")
	}

	switch val.Kind() {
	case reflect.String:
		val.SetString(value)
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		if val.Type() == reflect.TypeOf(time.Duration(0)) {
			d, err := time.ParseDuration(value)
			if err != nil {
				return fmt.Errorf("reflect: invalid duration: %v", value)
			}
			val.SetInt(int64(d))
		} else {
			i, err := strconv.ParseInt(value, 10, 64)
			if err != nil {
				return fmt.Errorf("reflect: invalid integer: %v", value)
			}
			val.SetInt(i)
		}
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		u, err := strconv.ParseUint(value, 10, 64)
		if err != nil {
			return fmt.Errorf("reflect: invalid unsigned integer: %v", value)
		}
		val.SetUint(u)
	case reflect.Float32, reflect.Float64:
		f, err := strconv.ParseFloat(value, 64)
		if err != nil {
			return fmt.Errorf("reflect: invalid float: %v", value)
		}
		val.SetFloat(f)
	case reflect.Bool:
		b, err := ParseBool(value)
		if err != nil {
			return fmt.Errorf("reflect: %w", err)
		}
		val.SetBool(b)
	case reflect.Slice:
		if val.Type().Elem().Kind() == reflect.String {
			val.Set(reflect.Append(val, reflect.ValueOf(value)))
		} else {
			return fmt.Errorf("reflect: unsupported slice type: %v", val.Type().Elem().Kind())
		}
	default:
		return fmt.Errorf("reflect: unsupported type: %v", val.Kind())
	}
	return nil
}

Example

var x int
err := reflect.Bind(reflect.ValueOf(&x).Elem(), "42")
F
function

ParseBool

ParseBool parses a boolean string with support for more formats.

It accepts 1, t, true, yes, y, on as true.
It accepts 0, f, false, no, n, off as false.

Parameters

str
string

Returns

bool
error
pkg/reflect/reflect.go:75-83
func ParseBool(str string) (bool, error)

{
	switch strings.ToLower(strings.TrimSpace(str)) {
	case "1", "t", "true", "yes", "y", "on":
		return true, nil
	case "0", "f", "false", "no", "n", "off":
		return false, nil
	}
	return false, fmt.Errorf("invalid boolean value: %s", str)
}
F
function

TestBind

Parameters

pkg/reflect/reflect_test.go:9-57
func TestBind(t *testing.T)

{
	t.Run("String", func(t *testing.T) {
		var s string
		err := Bind(reflect.ValueOf(&s).Elem(), "hello")
		if err != nil || s != "hello" {
			t.Errorf("Bind failed: %v, s=%q", err, s)
		}
	})

	t.Run("Int", func(t *testing.T) {
		var i int
		err := Bind(reflect.ValueOf(&i).Elem(), "42")
		if err != nil || i != 42 {
			t.Errorf("Bind failed: %v, i=%d", err, i)
		}
	})

	t.Run("Duration", func(t *testing.T) {
		var d time.Duration
		err := Bind(reflect.ValueOf(&d).Elem(), "5s")
		if err != nil || d != 5*time.Second {
			t.Errorf("Bind failed: %v, d=%v", err, d)
		}
	})

	t.Run("Bool", func(t *testing.T) {
		var b bool
		err := Bind(reflect.ValueOf(&b).Elem(), "yes")
		if err != nil || !b {
			t.Errorf("Bind failed: %v, b=%v", err, b)
		}
	})

	t.Run("Float", func(t *testing.T) {
		var f float64
		err := Bind(reflect.ValueOf(&f).Elem(), "3.14")
		if err != nil || f != 3.14 {
			t.Errorf("Bind failed: %v, f=%v", err, f)
		}
	})

	t.Run("Slice", func(t *testing.T) {
		var s []string
		err := Bind(reflect.ValueOf(&s).Elem(), "a")
		if err != nil || len(s) != 1 || s[0] != "a" {
			t.Errorf("Bind failed: %v, s=%v", err, s)
		}
	})
}
F
function

TestParseBool

Parameters

pkg/reflect/reflect_test.go:59-85
func TestParseBool(t *testing.T)

{
	tests := []struct {
		input string
		want  bool
		err   bool
	}{
		{"true", true, false},
		{"yes", true, false},
		{"on", true, false},
		{"1", true, false},
		{"false", false, false},
		{"no", false, false},
		{"off", false, false},
		{"0", false, false},
		{"invalid", false, true},
	}

	for _, tt := range tests {
		got, err := ParseBool(tt.input)
		if (err != nil) != tt.err {
			t.Errorf("ParseBool(%q) error = %v, wantErr %v", tt.input, err, tt.err)
		}
		if got != tt.want {
			t.Errorf("ParseBool(%q) = %v, want %v", tt.input, got, tt.want)
		}
	}
}