package Any import ( "bytes" "encoding/binary" "encoding/json" "fmt" "math" "reflect" "regexp" "strconv" ) // Bytes convert any to bytes func Bytes(value any) ([]byte, error) { v := reflect.ValueOf(value) switch value.(type) { case int, int8, int16, int32, int64: number := v.Int() buf := bytes.NewBuffer([]byte{}) buf.Reset() err := binary.Write(buf, binary.BigEndian, number) return buf.Bytes(), err case uint, uint8, uint16, uint32, uint64: number := v.Uint() buf := bytes.NewBuffer([]byte{}) buf.Reset() err := binary.Write(buf, binary.BigEndian, number) return buf.Bytes(), err case float32: number := float32(v.Float()) bits := math.Float32bits(number) bytes := make([]byte, 4) binary.BigEndian.PutUint32(bytes, bits) return bytes, nil case float64: number := v.Float() bits := math.Float64bits(number) bytes := make([]byte, 8) binary.BigEndian.PutUint64(bytes, bits) return bytes, nil case bool: return strconv.AppendBool([]byte{}, v.Bool()), nil case string: return []byte(v.String()), nil case []byte: return v.Bytes(), nil default: newValue, err := json.Marshal(value) return newValue, err } } // String convert value to string func String(value any) string { result := "" if value == nil { return result } v := reflect.ValueOf(value) switch value.(type) { case float32, float64: result = strconv.FormatFloat(v.Float(), 'f', -1, 64) return result case int, int8, int16, int32, int64: result = strconv.FormatInt(v.Int(), 10) return result case uint, uint8, uint16, uint32, uint64: result = strconv.FormatUint(v.Uint(), 10) return result case string: result = v.String() return result case []byte: result = string(v.Bytes()) return result default: newValue, _ := json.Marshal(value) result = string(newValue) return result } } // Float convert value to a float64, if input is not a float return 0.0 and error func Float(value any) (float64, error) { v := reflect.ValueOf(value) result := 0.0 err := fmt.Errorf("ToInt: unvalid interface type %T", value) switch value.(type) { case int, int8, int16, int32, int64: result = float64(v.Int()) return result, nil case uint, uint8, uint16, uint32, uint64: result = float64(v.Uint()) return result, nil case float32, float64: result = v.Float() return result, nil case string: result, err = strconv.ParseFloat(v.String(), 64) if err != nil { result = 0.0 } return result, err default: return result, err } } // Int convert value to a int64, if input is not a numeric format return 0 and error func Int(value any) (int64, error) { v := reflect.ValueOf(value) var result int64 err := fmt.Errorf("ToInt: invalid interface type %T", value) switch value.(type) { case int, int8, int16, int32, int64: result = v.Int() return result, nil case uint, uint8, uint16, uint32, uint64: result = int64(v.Uint()) return result, nil case float32, float64: result = int64(v.Float()) return result, nil case string: result, err = strconv.ParseInt(v.String(), 0, 64) if err != nil { result = 0 } return result, err default: return result, err } } // Pointer returns a pointer to this value func Pointer[T any](value T) *T { return &value } // Map convert a slice or an array of structs to a map based on iteratee function func Map[T any, K comparable, V any](array []T, iteratee func(T) (K, V)) map[K]V { result := make(map[K]V, len(array)) for _, item := range array { k, v := iteratee(item) result[k] = v } return result } // StructToMap convert struct to map, only convert exported struct field // map key is specified same as struct field tag `json` value func StructToMap(value any) (map[string]any, error) { v := reflect.ValueOf(value) t := reflect.TypeOf(value) if t.Kind() == reflect.Ptr { t = t.Elem() } if t.Kind() != reflect.Struct { return nil, fmt.Errorf("data type %T not support, shuld be struct or pointer to struct", value) } result := make(map[string]any) fieldNum := t.NumField() pattern := `^[A-Z]` regex := regexp.MustCompile(pattern) for i := 0; i < fieldNum; i++ { name := t.Field(i).Name tag := t.Field(i).Tag.Get("json") if regex.MatchString(name) && tag != "" { //result[name] = v.Field(i).Interface() result[tag] = v.Field(i).Interface() } } return result, nil } // MapToSlice convert a map to a slice based on iteratee function func MapToSlice[T any, K comparable, V any](aMap map[K]V, iteratee func(K, V) T) []T { result := make([]T, 0, len(aMap)) for k, v := range aMap { result = append(result, iteratee(k, v)) } return result } // Json convert value to a valid json string func Json(value any) (string, error) { result, err := json.Marshal(value) if err != nil { return "", err } return string(result), nil } // Channel convert a array of elements to a read-only channels func Channel[T any](array []T) <-chan T { ch := make(chan T) go func() { for _, item := range array { ch <- item } close(ch) }() return ch }