add convertor utils

This commit is contained in:
kenneth 2022-05-10 14:46:32 +08:00
parent d82220a8e1
commit fc6b263a85
4 changed files with 448 additions and 204 deletions

View File

@ -1,90 +0,0 @@
package conver
import (
"encoding/json"
"fmt"
"strconv"
"strings"
)
func FloatToString(val float64) string {
return strconv.FormatFloat(val, 'f', 1, 64)
}
func SliceIntToString(num []int64) string {
result := ""
if len(num) > 0 {
for _, item := range num {
result = fmt.Sprintf("%s,%d", result, item)
}
if !strings.HasSuffix(result, ",") {
result = fmt.Sprintf("%s,", result)
}
}
return result
}
func SliceStringToString(num []string) string {
result := ""
if len(num) > 0 {
for _, item := range num {
result = fmt.Sprintf("%s,%s", result, item)
}
if !strings.HasSuffix(result, ",") {
result = fmt.Sprintf("%s,", result)
}
}
return result
}
func StringToSlice(num string) []string {
var result []string
if len(num) > 0 {
result = strings.Split(num, ",")
}
return result
}
func StringToSliceInt(num string) []int64 {
var result []int64
if len(num) > 0 {
array := strings.Split(num, ",")
if len(array) > 0 {
for _, item := range array {
i, err := strconv.Atoi(item)
if err == nil {
result = append(result, int64(i))
}
}
}
}
return result
}
func MapToJson(param map[string]interface{}) string {
dataType, err := json.Marshal(param)
if err != nil {
return ""
}
dataString := string(dataType)
return dataString
}
func MapSliceStringToJson(param map[string][]string) string {
dataType, err := json.Marshal(param)
if err != nil {
return ""
}
dataString := string(dataType)
return dataString
}

286
pkg/convertor/convertor.go Normal file
View File

@ -0,0 +1,286 @@
// Package convertor 实现了一些函数来转换数据
package convertor
import (
"bytes"
"encoding/binary"
"encoding/json"
"fmt"
"math"
"reflect"
"regexp"
"strconv"
"strings"
)
// ToBool 将字符串转换为布尔值
func ToBool(s string) (bool, error) {
return strconv.ParseBool(s)
}
// ToBytes 将接口转换为字节数
func ToBytes(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
}
}
// ToChar 将字符串转换为char slice
func ToChar(s string) []string {
c := make([]string, 0)
if len(s) == 0 {
c = append(c, "")
}
for _, v := range s {
c = append(c, string(v))
}
return c
}
// ToString 将值转换为字符串
func ToString(value any) string {
res := ""
if value == nil {
return res
}
v := reflect.ValueOf(value)
switch value.(type) {
case float32, float64:
res = strconv.FormatFloat(v.Float(), 'f', -1, 64)
return res
case int, int8, int16, int32, int64:
res = strconv.FormatInt(v.Int(), 10)
return res
case uint, uint8, uint16, uint32, uint64:
res = strconv.FormatUint(v.Uint(), 10)
return res
case string:
res = v.String()
return res
case []byte:
res = string(v.Bytes())
return res
default:
newValue, _ := json.Marshal(value)
res = string(newValue)
return res
}
}
// ToJson 将值转换为有效的json字符串
func ToJson(value any) (string, error) {
res, err := json.Marshal(value)
if err != nil {
return "", err
}
return string(res), nil
}
// ToFloat 将数值转换为float64,如果输入的不是float,则返回0.0和错误
func ToFloat(value any) (float64, error) {
v := reflect.ValueOf(value)
res := 0.0
err := fmt.Errorf("ToInt: unvalid interface type %T", value)
switch value.(type) {
case int, int8, int16, int32, int64:
res = float64(v.Int())
return res, nil
case uint, uint8, uint16, uint32, uint64:
res = float64(v.Uint())
return res, nil
case float32, float64:
res = v.Float()
return res, nil
case string:
res, err = strconv.ParseFloat(v.String(), 64)
if err != nil {
res = 0.0
}
return res, err
default:
return res, err
}
}
// ToInt 将数值转换为int64,如果输入的不是数字格式,则返回0和错误
func ToInt(value any) (int64, error) {
v := reflect.ValueOf(value)
var res int64
err := fmt.Errorf("ToInt: invalid interface type %T", value)
switch value.(type) {
case int, int8, int16, int32, int64:
res = v.Int()
return res, nil
case uint, uint8, uint16, uint32, uint64:
res = int64(v.Uint())
return res, nil
case float32, float64:
res = int64(v.Float())
return res, nil
case string:
res, err = strconv.ParseInt(v.String(), 0, 64)
if err != nil {
res = 0
}
return res, err
default:
return res, err
}
}
// StructToMap 将结构体转换为Map,只转换导出的结构体字段
// Map key的指定与结构字段标签`json`值相同
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)
}
res := 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 != "" {
//res[name] = v.Field(i).Interface()
res[tag] = v.Field(i).Interface()
}
}
return res, nil
}
// ColorHexToRGB 将十六进制颜色转换为RGB颜色
func ColorHexToRGB(colorHex string) (red, green, blue int) {
colorHex = strings.TrimPrefix(colorHex, "#")
color64, err := strconv.ParseInt(colorHex, 16, 32)
if err != nil {
return
}
color := int(color64)
return color >> 16, (color & 0x00FF00) >> 8, color & 0x0000FF
}
// ColorRGBToHex 将RGB颜色转换为十六进制颜色
func ColorRGBToHex(red, green, blue int) string {
r := strconv.FormatInt(int64(red), 16)
g := strconv.FormatInt(int64(green), 16)
b := strconv.FormatInt(int64(blue), 16)
if len(r) == 1 {
r = "0" + r
}
if len(g) == 1 {
g = "0" + g
}
if len(b) == 1 {
b = "0" + b
}
return "#" + r + g + b
}
// Strval 获取变量的字符串值
// 浮点型 3.0将会转换成字符串3, "3"
// 非数值或字符类型的变量将会被转换成JSON格式字符串
func Strval(value interface{}) string {
// interface 转 string
var key string
if value == nil {
return key
}
switch value.(type) {
case float64:
ft := value.(float64)
key = strconv.FormatFloat(ft, 'f', -1, 64)
case float32:
ft := value.(float32)
key = strconv.FormatFloat(float64(ft), 'f', -1, 64)
case int:
it := value.(int)
key = strconv.Itoa(it)
case uint:
it := value.(uint)
key = strconv.Itoa(int(it))
case int8:
it := value.(int8)
key = strconv.Itoa(int(it))
case uint8:
it := value.(uint8)
key = strconv.Itoa(int(it))
case int16:
it := value.(int16)
key = strconv.Itoa(int(it))
case uint16:
it := value.(uint16)
key = strconv.Itoa(int(it))
case int32:
it := value.(int32)
key = strconv.Itoa(int(it))
case uint32:
it := value.(uint32)
key = strconv.Itoa(int(it))
case int64:
it := value.(int64)
key = strconv.FormatInt(it, 10)
case uint64:
it := value.(uint64)
key = strconv.FormatUint(it, 10)
case string:
key = value.(string)
case []byte:
key = string(value.([]byte))
default:
newValue, _ := json.Marshal(value)
key = string(newValue)
}
return key
}

View File

@ -0,0 +1,162 @@
package convertor
import (
"fmt"
"testing"
"github.com/stretchr/testify/require"
)
func TestToChar(t *testing.T) {
cases := []string{"", "abc", "1 2#3"}
expected := [][]string{
{""},
{"a", "b", "c"},
{"1", " ", "2", "#", "3"},
}
for i := 0; i < len(cases); i++ {
require.Equal(t, expected[i], ToChar(cases[i]))
}
}
func TestToBool(t *testing.T) {
cases := []string{"1", "true", "True", "false", "False", "0", "123", "0.0", "abc"}
expected := []bool{true, true, true, false, false, false, false, false, false}
for i := 0; i < len(cases); i++ {
actual, _ := ToBool(cases[i])
require.Equal(t, expected[i], actual)
}
}
func TestToBytes(t *testing.T) {
cases := []any{
0,
false,
"1",
}
expected := [][]byte{
{0, 0, 0, 0, 0, 0, 0, 0},
{102, 97, 108, 115, 101},
{49},
}
for i := 0; i < len(cases); i++ {
actual, _ := ToBytes(cases[i])
require.Equal(t, expected[i], actual)
}
bytesData, err := ToBytes("abc")
if err != nil {
t.Error(err)
t.Fail()
}
require.Equal(t, "abc", ToString(bytesData))
}
func TestToInt(t *testing.T) {
cases := []any{"123", "-123", 123,
uint(123), uint8(123), uint16(123), uint32(123), uint64(123),
float32(12.3), float64(12.3),
"abc", false, "111111111111111111111111111111111111111"}
expected := []int64{123, -123, 123, 123, 123, 123, 123, 123, 12, 12, 0, 0, 0}
for i := 0; i < len(cases); i++ {
actual, _ := ToInt(cases[i])
require.Equal(t, expected[i], actual)
}
}
func TestToFloat(t *testing.T) {
cases := []any{
"", "-1", "-.11", "1.23e3", ".123e10", "abc",
int(0), int8(1), int16(-1), int32(123), int64(123),
uint(123), uint8(123), uint16(123), uint32(123), uint64(123),
float64(12.3), float32(12.3),
}
expected := []float64{0, -1, -0.11, 1230, 0.123e10, 0,
0, 1, -1, 123, 123, 123, 123, 123, 123, 123, 12.3, 12.300000190734863}
for i := 0; i < len(cases); i++ {
actual, _ := ToFloat(cases[i])
require.Equal(t, expected[i], actual)
}
}
func TestToString(t *testing.T) {
aMap := make(map[string]int)
aMap["a"] = 1
aMap["b"] = 2
aMap["c"] = 3
type TestStruct struct {
Name string
}
aStruct := TestStruct{Name: "TestStruct"}
cases := []any{
"", nil,
int(0), int8(1), int16(-1), int32(123), int64(123),
uint(123), uint8(123), uint16(123), uint32(123), uint64(123),
float64(12.3), float32(12.3),
true, false,
[]int{1, 2, 3}, aMap, aStruct, []byte{104, 101, 108, 108, 111}}
expected := []string{
"", "",
"0", "1", "-1",
"123", "123", "123", "123", "123", "123", "123",
"12.3", "12.300000190734863",
"true", "false",
"[1,2,3]", "{\"a\":1,\"b\":2,\"c\":3}", "{\"Name\":\"TestStruct\"}", "hello"}
for i := 0; i < len(cases); i++ {
actual := ToString(cases[i])
require.Equal(t, expected[i], actual)
}
}
func TestToJson(t *testing.T) {
var aMap = map[string]int{"a": 1, "b": 2, "c": 3}
mapJsonStr, _ := ToJson(aMap)
require.Equal(t, "{\"a\":1,\"b\":2,\"c\":3}", mapJsonStr)
type TestStruct struct {
Name string
}
aStruct := TestStruct{Name: "TestStruct"}
structJsonStr, _ := ToJson(aStruct)
require.Equal(t, "{\"Name\":\"TestStruct\"}", structJsonStr)
}
func TestStructToMap(t *testing.T) {
type People struct {
Name string `json:"name"`
age int
}
p := People{
"test",
100,
}
pm, _ := StructToMap(p)
var expected = map[string]any{"name": "test"}
require.Equal(t, expected, pm)
}
func TestColorHexToRGB(t *testing.T) {
colorHex := "#003366"
r, g, b := ColorHexToRGB(colorHex)
colorRGB := fmt.Sprintf("%d,%d,%d", r, g, b)
expected := "0,51,102"
require.Equal(t, expected, colorRGB)
}
func TestColorRGBToHex(t *testing.T) {
r := 0
g := 51
b := 102
colorHex := ColorRGBToHex(r, g, b)
expected := "#003366"
require.Equal(t, expected, colorHex)
}

View File

@ -1,114 +0,0 @@
package st
import (
"encoding/json"
"regexp"
"strconv"
"strings"
)
func RemoveHTML(str string) string {
if len(str) > 0 {
//删除脚本
reg := regexp.MustCompile(`([\r\n])[\s]+`)
str = reg.ReplaceAllString(str, "")
reg = regexp.MustCompile(`<script[^>]*?>.*?</script>`)
str = reg.ReplaceAllString(str, "")
//删除HTML
reg = regexp.MustCompile(`<(.[^>]*)>`)
str = reg.ReplaceAllString(str, "")
reg = regexp.MustCompile(`([\r\n])[\s]+`)
str = reg.ReplaceAllString(str, "")
reg = regexp.MustCompile(`-->`)
str = reg.ReplaceAllString(str, "")
reg = regexp.MustCompile(`<!--.*`)
str = reg.ReplaceAllString(str, "")
reg = regexp.MustCompile(`&(quot|#34);`)
str = reg.ReplaceAllString(str, "")
reg = regexp.MustCompile(`&(amp|#38);`)
str = reg.ReplaceAllString(str, "")
reg = regexp.MustCompile(`&(lt|#60);`)
str = reg.ReplaceAllString(str, "")
reg = regexp.MustCompile(`&(gt|#62);`)
str = reg.ReplaceAllString(str, "")
reg = regexp.MustCompile(`&(nbsp|#160);`)
str = reg.ReplaceAllString(str, "")
reg = regexp.MustCompile(`&(iexcl|#161);`)
str = reg.ReplaceAllString(str, "")
reg = regexp.MustCompile(`&(cent|#162);`)
str = reg.ReplaceAllString(str, "")
reg = regexp.MustCompile(`&(pound|#163);`)
str = reg.ReplaceAllString(str, "")
reg = regexp.MustCompile(`&(copy|#169);`)
str = reg.ReplaceAllString(str, "")
reg = regexp.MustCompile(`&#(\d+);`)
str = reg.ReplaceAllString(str, "")
str = strings.ReplaceAll(str, "<", "")
str = strings.ReplaceAll(str, ">", "")
str = strings.ReplaceAll(str, "\n", "")
str = strings.ReplaceAll(str, " ", "")
str = strings.ReplaceAll(str, " ", "")
return str
}
return ""
}
// Strval 获取变量的字符串值
// 浮点型 3.0将会转换成字符串3, "3"
// 非数值或字符类型的变量将会被转换成JSON格式字符串
func Strval(value interface{}) string {
// interface 转 string
var key string
if value == nil {
return key
}
switch value.(type) {
case float64:
ft := value.(float64)
key = strconv.FormatFloat(ft, 'f', -1, 64)
case float32:
ft := value.(float32)
key = strconv.FormatFloat(float64(ft), 'f', -1, 64)
case int:
it := value.(int)
key = strconv.Itoa(it)
case uint:
it := value.(uint)
key = strconv.Itoa(int(it))
case int8:
it := value.(int8)
key = strconv.Itoa(int(it))
case uint8:
it := value.(uint8)
key = strconv.Itoa(int(it))
case int16:
it := value.(int16)
key = strconv.Itoa(int(it))
case uint16:
it := value.(uint16)
key = strconv.Itoa(int(it))
case int32:
it := value.(int32)
key = strconv.Itoa(int(it))
case uint32:
it := value.(uint32)
key = strconv.Itoa(int(it))
case int64:
it := value.(int64)
key = strconv.FormatInt(it, 10)
case uint64:
it := value.(uint64)
key = strconv.FormatUint(it, 10)
case string:
key = value.(string)
case []byte:
key = string(value.([]byte))
default:
newValue, _ := json.Marshal(value)
key = string(newValue)
}
return key
}