// Copyright © 2014 Steve Francia . // // Use of this source code is governed by an MIT-style // license that can be found in the LICENSE file. package cast import ( "encoding/json" "fmt" "html/template" "strconv" "time" ) // ToBoolE casts any value to a bool type. func ToBoolE(i any) (bool, error) { i, _ = indirect(i) switch b := i.(type) { case bool: return b, nil case nil: return false, nil case int: return b != 0, nil case int8: return b != 0, nil case int16: return b != 0, nil case int32: return b != 0, nil case int64: return b != 0, nil case uint: return b != 0, nil case uint8: return b != 0, nil case uint16: return b != 0, nil case uint32: return b != 0, nil case uint64: return b != 0, nil case float32: return b != 0, nil case float64: return b != 0, nil case time.Duration: return b != 0, nil case string: return strconv.ParseBool(b) case json.Number: v, err := ToInt64E(b) if err == nil { return v != 0, nil } return false, fmt.Errorf(errorMsg, i, i, false) default: if i, ok := resolveAlias(i); ok { return ToBoolE(i) } return false, fmt.Errorf(errorMsg, i, i, false) } } // ToStringE casts any value to a string type. func ToStringE(i any) (string, error) { switch s := i.(type) { case string: return s, nil case bool: return strconv.FormatBool(s), nil case float64: return strconv.FormatFloat(s, 'f', -1, 64), nil case float32: return strconv.FormatFloat(float64(s), 'f', -1, 32), nil case int: return strconv.Itoa(s), nil case int8: return strconv.FormatInt(int64(s), 10), nil case int16: return strconv.FormatInt(int64(s), 10), nil case int32: return strconv.FormatInt(int64(s), 10), nil case int64: return strconv.FormatInt(s, 10), nil case uint: return strconv.FormatUint(uint64(s), 10), nil case uint8: return strconv.FormatUint(uint64(s), 10), nil case uint16: return strconv.FormatUint(uint64(s), 10), nil case uint32: return strconv.FormatUint(uint64(s), 10), nil case uint64: return strconv.FormatUint(s, 10), nil case json.Number: return s.String(), nil case []byte: return string(s), nil case template.HTML: return string(s), nil case template.URL: return string(s), nil case template.JS: return string(s), nil case template.CSS: return string(s), nil case template.HTMLAttr: return string(s), nil case nil: return "", nil case fmt.Stringer: return s.String(), nil case error: return s.Error(), nil default: if i, ok := indirect(i); ok { return ToStringE(i) } if i, ok := resolveAlias(i); ok { return ToStringE(i) } return "", fmt.Errorf(errorMsg, i, i, "") } }