134 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package utils
 | 
						|
 | 
						|
import (
 | 
						|
	"encoding/binary"
 | 
						|
	"encoding/json"
 | 
						|
	"fmt"
 | 
						|
	"hash/fnv"
 | 
						|
	"math"
 | 
						|
	"strconv"
 | 
						|
 | 
						|
	"github.com/golang-jwt/jwt/v5"
 | 
						|
)
 | 
						|
 | 
						|
type WbAuthData struct {
 | 
						|
	Token string `json:"token"`
 | 
						|
}
 | 
						|
 | 
						|
func NewWbAuthData(token string) WbAuthData {
 | 
						|
	return WbAuthData{
 | 
						|
		Token: token,
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func DecodeWildberriesJwt(token []byte) (WbAuthData, jwt.MapClaims, error) {
 | 
						|
	var authData WbAuthData
 | 
						|
	err := json.Unmarshal(token, &authData)
 | 
						|
	if err != nil {
 | 
						|
		return authData, nil, fmt.Errorf("failed to unmarshal JWT: %w", err)
 | 
						|
	}
 | 
						|
	claims := jwt.MapClaims{}
 | 
						|
	_, _, err = jwt.NewParser().ParseUnverified(authData.Token, claims)
 | 
						|
	if err != nil {
 | 
						|
		return authData, nil, fmt.Errorf("invalid JWT: %w", err)
 | 
						|
	}
 | 
						|
 | 
						|
	return authData, claims, nil
 | 
						|
}
 | 
						|
 | 
						|
func ToPtrs[T any](s []T) []*T {
 | 
						|
	res := make([]*T, len(s))
 | 
						|
	for i := range s {
 | 
						|
		res[i] = &s[i]
 | 
						|
	}
 | 
						|
	return res
 | 
						|
}
 | 
						|
 | 
						|
func DerefSlice[T any](s []*T) []T {
 | 
						|
	res := make([]T, len(s))
 | 
						|
	for i := range s {
 | 
						|
		if s[i] != nil {
 | 
						|
			res[i] = *s[i]
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return res
 | 
						|
}
 | 
						|
 | 
						|
type Hashable interface {
 | 
						|
	~int | ~int8 | ~int16 | ~int32 | ~int64 |
 | 
						|
		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 |
 | 
						|
		~string | ~bool | ~float32 | ~float64
 | 
						|
}
 | 
						|
 | 
						|
func HashArray[T Hashable](arr []T) (string, error) {
 | 
						|
	h := fnv.New64a()
 | 
						|
	buf := make([]byte, 8)
 | 
						|
 | 
						|
	for _, v := range arr {
 | 
						|
		var b []byte
 | 
						|
 | 
						|
		switch val := any(v).(type) {
 | 
						|
		case int:
 | 
						|
			binary.LittleEndian.PutUint64(buf, uint64(val))
 | 
						|
			b = buf
 | 
						|
		case int8:
 | 
						|
			buf[0] = byte(val)
 | 
						|
			b = buf[:1]
 | 
						|
		case int16:
 | 
						|
			binary.LittleEndian.PutUint16(buf, uint16(val))
 | 
						|
			b = buf[:2]
 | 
						|
		case int32:
 | 
						|
			binary.LittleEndian.PutUint32(buf, uint32(val))
 | 
						|
			b = buf[:4]
 | 
						|
		case int64:
 | 
						|
			binary.LittleEndian.PutUint64(buf, uint64(val))
 | 
						|
			b = buf
 | 
						|
		case uint:
 | 
						|
			binary.LittleEndian.PutUint64(buf, uint64(val))
 | 
						|
			b = buf
 | 
						|
		case uint8:
 | 
						|
			buf[0] = val
 | 
						|
			b = buf[:1]
 | 
						|
		case uint16:
 | 
						|
			binary.LittleEndian.PutUint16(buf, val)
 | 
						|
			b = buf[:2]
 | 
						|
		case uint32:
 | 
						|
			binary.LittleEndian.PutUint32(buf, val)
 | 
						|
			b = buf[:4]
 | 
						|
		case uint64:
 | 
						|
			binary.LittleEndian.PutUint64(buf, val)
 | 
						|
			b = buf
 | 
						|
		case float32:
 | 
						|
			binary.LittleEndian.PutUint32(buf[:4], math.Float32bits(val))
 | 
						|
			b = buf[:4]
 | 
						|
		case float64:
 | 
						|
			binary.LittleEndian.PutUint64(buf, math.Float64bits(val))
 | 
						|
			b = buf
 | 
						|
		case bool:
 | 
						|
			if val {
 | 
						|
				buf[0] = 1
 | 
						|
			} else {
 | 
						|
				buf[0] = 0
 | 
						|
			}
 | 
						|
			b = buf[:1]
 | 
						|
		case string:
 | 
						|
			b = []byte(val)
 | 
						|
		default:
 | 
						|
			return "", fmt.Errorf("unsupported type: %T", val)
 | 
						|
		}
 | 
						|
 | 
						|
		if _, err := h.Write(b); err != nil {
 | 
						|
			return "", fmt.Errorf("failed to write to hash: %w", err)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return fmt.Sprintf("%x", h.Sum64()), nil
 | 
						|
}
 | 
						|
 | 
						|
func IsDigit(v string) (bool, *int64) {
 | 
						|
	if val, err := strconv.ParseInt(v, 10, 64); err == nil {
 | 
						|
		return true, &val
 | 
						|
	}
 | 
						|
	return false, nil
 | 
						|
}
 |