You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Open-IM-Server/pkg/utils/utils.go

256 lines
5.0 KiB

package utils
import (
"bytes"
"encoding/json"
"github.com/gogo/protobuf/jsonpb"
"github.com/golang/protobuf/proto"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
"hash/crc32"
"math/rand"
"reflect"
"runtime"
"strconv"
"strings"
"time"
)
// copy a by b b->a
func CopyStructFields(a interface{}, b interface{}, fields ...string) (err error) {
return copier.Copy(a, b)
}
func Wrap1(err error) error {
if err != nil {
return Wrap(err, "")
}
return nil
}
func Wrap2[T any](a T, err error) (T, error) {
if err != nil {
return a, Wrap(err, "")
}
return a, nil
}
func Wrap3[T any, V any](a T, b V, err error) (T, V, error) {
if err != nil {
return a, b, Wrap(err, "")
}
return a, b, nil
}
func Wrap(err error, message string) error {
return errors.Wrap(err, "==> "+printCallerNameAndLine()+message)
}
func WithMessage(err error, message string) error {
return errors.WithMessage(err, "==> "+printCallerNameAndLine()+message)
}
func printCallerNameAndLine() string {
pc, _, line, _ := runtime.Caller(2)
return runtime.FuncForPC(pc).Name() + "()@" + strconv.Itoa(line) + ": "
}
func GetSelfFuncName() string {
pc, _, _, _ := runtime.Caller(1)
return cleanUpFuncName(runtime.FuncForPC(pc).Name())
}
func GetFuncName(skips ...int) string {
skip := 1
if len(skips) > 0 {
skip = skips[0] + 1
}
pc, _, _, _ := runtime.Caller(skip)
return cleanUpFuncName(runtime.FuncForPC(pc).Name())
}
func cleanUpFuncName(funcName string) string {
end := strings.LastIndex(funcName, ".")
if end == -1 {
return ""
}
return funcName[end+1:]
}
// Get the intersection of two slices
func Intersect(slice1, slice2 []int64) []int64 {
m := make(map[int64]bool)
n := make([]int64, 0)
for _, v := range slice1 {
m[v] = true
}
for _, v := range slice2 {
flag, _ := m[v]
if flag {
n = append(n, v)
}
}
return n
}
// Get the diff of two slices
func Difference(slice1, slice2 []int64) []int64 {
m := make(map[int64]bool)
n := make([]int64, 0)
inter := Intersect(slice1, slice2)
for _, v := range inter {
m[v] = true
}
for _, v := range slice1 {
if !m[v] {
n = append(n, v)
}
}
for _, v := range slice2 {
if !m[v] {
n = append(n, v)
}
}
return n
}
// Get the intersection of two slices
func IntersectString(slice1, slice2 []string) []string {
m := make(map[string]bool)
n := make([]string, 0)
for _, v := range slice1 {
m[v] = true
}
for _, v := range slice2 {
flag, _ := m[v]
if flag {
n = append(n, v)
}
}
return n
}
// Get the diff of two slices
func DifferenceString(slice1, slice2 []string) []string {
m := make(map[string]bool)
n := make([]string, 0)
inter := IntersectString(slice1, slice2)
for _, v := range inter {
m[v] = true
}
for _, v := range slice1 {
if !m[v] {
n = append(n, v)
}
}
for _, v := range slice2 {
if !m[v] {
n = append(n, v)
}
}
return n
}
func OperationIDGenerator() string {
return strconv.FormatInt(time.Now().UnixNano()+int64(rand.Uint32()), 10)
}
func RemoveRepeatedStringInList(slc []string) []string {
var result []string
tempMap := map[string]byte{}
for _, e := range slc {
l := len(tempMap)
tempMap[e] = 0
if len(tempMap) != l {
result = append(result, e)
}
}
return result
}
func Pb2String(pb proto.Message) (string, error) {
marshaler := jsonpb.Marshaler{
OrigName: true,
EnumsAsInts: false,
EmitDefaults: false,
}
return marshaler.MarshalToString(pb)
}
func String2Pb(s string, pb proto.Message) error {
return proto.Unmarshal([]byte(s), pb)
}
func Map2Pb(m map[string]string) (pb proto.Message, err error) {
b, err := json.Marshal(m)
if err != nil {
return nil, err
}
err = proto.Unmarshal(b, pb)
if err != nil {
return nil, err
}
return pb, nil
}
func Pb2Map(pb proto.Message) (map[string]interface{}, error) {
_buffer := bytes.Buffer{}
jsonbMarshaller := &jsonpb.Marshaler{
OrigName: true,
EnumsAsInts: true,
EmitDefaults: false,
}
_ = jsonbMarshaller.Marshal(&_buffer, pb)
jsonCnt := _buffer.Bytes()
var out map[string]interface{}
err := json.Unmarshal(jsonCnt, &out)
return out, err
}
func JsonDataList(resp interface{}) []map[string]interface{} {
var list []proto.Message
if reflect.TypeOf(resp).Kind() == reflect.Slice {
s := reflect.ValueOf(resp)
for i := 0; i < s.Len(); i++ {
ele := s.Index(i)
list = append(list, ele.Interface().(proto.Message))
}
}
result := make([]map[string]interface{}, 0)
for _, v := range list {
m := ProtoToMap(v, false)
result = append(result, m)
}
return result
}
func JsonDataOne(pb proto.Message) map[string]interface{} {
return ProtoToMap(pb, false)
}
func ProtoToMap(pb proto.Message, idFix bool) map[string]interface{} {
marshaler := jsonpb.Marshaler{
OrigName: true,
EnumsAsInts: false,
EmitDefaults: false,
}
s, _ := marshaler.MarshalToString(pb)
out := make(map[string]interface{})
json.Unmarshal([]byte(s), &out)
if idFix {
if _, ok := out["id"]; ok {
out["_id"] = out["id"]
delete(out, "id")
}
}
return out
}
func GetHashCode(s string) uint32 {
return crc32.ChecksumIEEE([]byte(s))
}