github.com/songzhibin97/go-baseutils@v0.0.2-0.20240302024150-487d8ce9c082/base/banytostring/anytostring.go (about)

     1  package banytostring
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"html/template"
     7  	"reflect"
     8  	"strconv"
     9  )
    10  
    11  func indirectToStringerOrError(a interface{}) interface{} {
    12  	if a == nil {
    13  		return nil
    14  	}
    15  
    16  	var errorType = reflect.TypeOf((*error)(nil)).Elem()
    17  	var fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
    18  
    19  	v := reflect.ValueOf(a)
    20  	for !v.Type().Implements(fmtStringerType) && !v.Type().Implements(errorType) && v.Kind() == reflect.Ptr && !v.IsNil() {
    21  		v = v.Elem()
    22  	}
    23  	return v.Interface()
    24  }
    25  
    26  func ToStringE(i interface{}) (string, error) { // ToStringE// ToStringE
    27  	// @Description:
    28  	// @param i:
    29  	// @return string
    30  	// @return error
    31  	// @Description:
    32  	// @param i:
    33  	// @return string
    34  	// @return error
    35  	i = indirectToStringerOrError(i)
    36  
    37  	switch s := i.(type) {
    38  	case string:
    39  		return s, nil
    40  	case bool:
    41  		return strconv.FormatBool(s), nil
    42  	case float64:
    43  		return strconv.FormatFloat(s, 'f', -1, 64), nil
    44  	case float32:
    45  		return strconv.FormatFloat(float64(s), 'f', -1, 32), nil
    46  	case int:
    47  		return strconv.Itoa(s), nil
    48  	case int64:
    49  		return strconv.FormatInt(s, 10), nil
    50  	case int32:
    51  		return strconv.Itoa(int(s)), nil
    52  	case int16:
    53  		return strconv.FormatInt(int64(s), 10), nil
    54  	case int8:
    55  		return strconv.FormatInt(int64(s), 10), nil
    56  	case uint:
    57  		return strconv.FormatUint(uint64(s), 10), nil
    58  	case uint64:
    59  		return strconv.FormatUint(uint64(s), 10), nil
    60  	case uint32:
    61  		return strconv.FormatUint(uint64(s), 10), nil
    62  	case uint16:
    63  		return strconv.FormatUint(uint64(s), 10), nil
    64  	case uint8:
    65  		return strconv.FormatUint(uint64(s), 10), nil
    66  	case json.Number:
    67  		return s.String(), nil
    68  	case []byte:
    69  		return string(s), nil
    70  	case template.HTML:
    71  		return string(s), nil
    72  	case template.URL:
    73  		return string(s), nil
    74  	case template.JS:
    75  		return string(s), nil
    76  	case template.CSS:
    77  		return string(s), nil
    78  	case template.HTMLAttr:
    79  		return string(s), nil
    80  	case nil:
    81  		return "", nil
    82  	case fmt.Stringer:
    83  		return s.String(), nil
    84  	case error:
    85  		return s.Error(), nil
    86  	default:
    87  		return "", fmt.Errorf("unable to cast %#v of type %T to string", i, i)
    88  	}
    89  }
    90  
    91  func ToString(v any) string {
    92  	nv, err := ToStringE(v)
    93  	if err != nil {
    94  		return fmt.Sprintf("%v", v)
    95  	}
    96  	return nv
    97  }