Initial commit
This commit is contained in:
commit
02a6dabcfb
62 files changed
+15751
No files matched your search
@@ -0,0 +1,126 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// JSONBackend defines the interface for JSON encoding/decoding
|
||||
type JSONBackend interface {
|
||||
Marshal(v any) ([]byte, error)
|
||||
Unmarshal(data []byte, v any) error
|
||||
}
|
||||
|
||||
// DefaultJSONBackend uses the standard library encoding/json
|
||||
type DefaultJSONBackend struct{}
|
||||
|
||||
func (DefaultJSONBackend) Marshal(v any) ([]byte, error) {
|
||||
return json.Marshal(v)
|
||||
}
|
||||
|
||||
func (DefaultJSONBackend) Unmarshal(data []byte, v any) error {
|
||||
return json.Unmarshal(data, v)
|
||||
}
|
||||
|
||||
// GetDefaultJSONBackend returns the default JSON backend
|
||||
func GetDefaultJSONBackend() JSONBackend {
|
||||
return DefaultJSONBackend{}
|
||||
}
|
||||
|
||||
// RawMessage is a raw encoded JSON value
|
||||
type RawMessage = json.RawMessage
|
||||
|
||||
// Marshal is a convenience function
|
||||
func Marshal(v any) ([]byte, error) {
|
||||
return GetDefaultJSONBackend().Marshal(v)
|
||||
}
|
||||
|
||||
// Unmarshal is a convenience function
|
||||
func Unmarshal(data []byte, v any) error {
|
||||
return GetDefaultJSONBackend().Unmarshal(data, v)
|
||||
}
|
||||
|
||||
// ToSnakeCase converts camelCase to snake_case
|
||||
func ToSnakeCase(s string) string {
|
||||
if s == "" {
|
||||
return s
|
||||
}
|
||||
var result strings.Builder
|
||||
for i, r := range s {
|
||||
if r >= 'A' && r <= 'Z' {
|
||||
if i > 0 {
|
||||
result.WriteRune('_')
|
||||
}
|
||||
result.WriteRune(r + 'a' - 'A')
|
||||
} else {
|
||||
result.WriteRune(r)
|
||||
}
|
||||
}
|
||||
return result.String()
|
||||
}
|
||||
|
||||
// ToCamelCase converts snake_case to camelCase
|
||||
func ToCamelCase(s string) string {
|
||||
if s == "" {
|
||||
return s
|
||||
}
|
||||
parts := strings.Split(s, "_")
|
||||
if len(parts) == 1 {
|
||||
return s
|
||||
}
|
||||
var result strings.Builder
|
||||
result.WriteString(parts[0])
|
||||
for _, part := range parts[1:] {
|
||||
if len(part) > 0 {
|
||||
result.WriteString(strings.ToUpper(part[:1]) + part[1:])
|
||||
}
|
||||
}
|
||||
return result.String()
|
||||
}
|
||||
|
||||
// MapKeysToSnakeCase converts all keys in a map to snake_case
|
||||
func MapKeysToSnakeCase(m map[string]any) map[string]any {
|
||||
result := make(map[string]any, len(m))
|
||||
for k, v := range m {
|
||||
result[ToSnakeCase(k)] = v
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// MapKeysToCamelCase converts all keys in a map to camelCase
|
||||
func MapKeysToCamelCase(m map[string]any) map[string]any {
|
||||
result := make(map[string]any, len(m))
|
||||
for k, v := range m {
|
||||
result[ToCamelCase(k)] = v
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// StructToMap converts a struct to a map using json tags
|
||||
func StructToMap(v any, forRequest bool) (map[string]any, error) {
|
||||
data, err := Marshal(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result map[string]any
|
||||
if err := Unmarshal(data, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetJSONTag returns the json tag for a struct field
|
||||
func GetJSONTag(t reflect.Type, fieldIndex int) string {
|
||||
if fieldIndex >= t.NumField() {
|
||||
return ""
|
||||
}
|
||||
field := t.Field(fieldIndex)
|
||||
tag := field.Tag.Get("json")
|
||||
if tag == "" || tag == "-" {
|
||||
return ""
|
||||
}
|
||||
// Parse tag options (e.g., "name,omitempty")
|
||||
parts := strings.Split(tag, ",")
|
||||
return parts[0]
|
||||
}
|
||||
Reference in new issue
Block a user