[feat] 重新梳理依赖
This commit is contained in:
@@ -1,228 +0,0 @@
|
||||
package support
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/samber/lo"
|
||||
"github.com/spf13/cast"
|
||||
"github.com/tidwall/gjson"
|
||||
"github.com/tidwall/sjson"
|
||||
|
||||
"git.fsdpf.net/go/contracts"
|
||||
)
|
||||
|
||||
type GlobalParams struct {
|
||||
user *contracts.User
|
||||
gjson gjson.Result
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
func (this GlobalParams) User() contracts.User {
|
||||
return *this.user
|
||||
}
|
||||
|
||||
// 获取指定路径的 value
|
||||
func (this GlobalParams) Get(key string) contracts.GlobalParams {
|
||||
return &GlobalParams{
|
||||
user: this.user,
|
||||
gjson: this.gjson.Get(key),
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
func (this GlobalParams) Array() []contracts.GlobalParams {
|
||||
return lo.Map(this.gjson.Array(), func(item gjson.Result, _ int) contracts.GlobalParams {
|
||||
return &GlobalParams{user: this.user, gjson: gjson.Parse(item.Raw)}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取golang原始类型
|
||||
func (this GlobalParams) Value() any {
|
||||
return this.gjson.Value()
|
||||
}
|
||||
|
||||
func (this GlobalParams) Raw() string {
|
||||
return this.gjson.Raw
|
||||
}
|
||||
|
||||
// 设置json值
|
||||
func (this *GlobalParams) Set(p string, v any) bool {
|
||||
if s, err := sjson.Set(this.Raw(), p, v); err != nil {
|
||||
return false
|
||||
} else {
|
||||
this.gjson = gjson.Parse(s)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// 设置json原始值
|
||||
func (this *GlobalParams) SetRaw(p, v string) bool {
|
||||
if s, err := sjson.SetRaw(this.Raw(), p, v); err != nil {
|
||||
return false
|
||||
} else {
|
||||
this.gjson = gjson.Parse(s)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// 删除路径内容
|
||||
func (this *GlobalParams) Delete(p string) bool {
|
||||
if s, err := sjson.Delete(this.Raw(), p); err != nil {
|
||||
return false
|
||||
} else {
|
||||
this.gjson = gjson.Parse(s)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// 路径包裹
|
||||
func (this *GlobalParams) Wrapped(p string) contracts.GlobalParams {
|
||||
return this.AppendTo("", p)
|
||||
}
|
||||
|
||||
// 包裹内容
|
||||
func (this *GlobalParams) AppendTo(root, p string) contracts.GlobalParams {
|
||||
if root != "" && !gjson.Valid(root) {
|
||||
root = ""
|
||||
}
|
||||
return NewGlobalParam(lo.Must(sjson.SetRaw(root, p, this.Raw())), *this.user)
|
||||
}
|
||||
|
||||
// 判断值是否存在
|
||||
func (this GlobalParams) Exists() bool {
|
||||
return this.gjson.Exists()
|
||||
}
|
||||
|
||||
// to Bool
|
||||
func (this GlobalParams) Bool() bool {
|
||||
return cast.ToBool(this.Value())
|
||||
}
|
||||
|
||||
// to Time
|
||||
func (this GlobalParams) Time() time.Time {
|
||||
return cast.ToTime(this.Value())
|
||||
}
|
||||
|
||||
// to Location Time
|
||||
func (this GlobalParams) TimeInDefaultLocation(location *time.Location) time.Time {
|
||||
return cast.ToTimeInDefaultLocation(this, location)
|
||||
}
|
||||
|
||||
// to float64
|
||||
func (this GlobalParams) Float64() float64 {
|
||||
return cast.ToFloat64(this.Value())
|
||||
}
|
||||
|
||||
// to float32
|
||||
func (this GlobalParams) Float32() float32 {
|
||||
return cast.ToFloat32(this.Value())
|
||||
}
|
||||
|
||||
// to int64
|
||||
func (this GlobalParams) Int64() int64 {
|
||||
return cast.ToInt64(this.Value())
|
||||
}
|
||||
|
||||
// to int32
|
||||
func (this GlobalParams) Int32() int32 {
|
||||
return cast.ToInt32(this.Value())
|
||||
}
|
||||
|
||||
// to int16
|
||||
func (this GlobalParams) Int16() int16 {
|
||||
return cast.ToInt16(this.Value())
|
||||
}
|
||||
|
||||
// to int8
|
||||
func (this GlobalParams) Int8() int8 {
|
||||
return cast.ToInt8(this.Value())
|
||||
}
|
||||
|
||||
// to int
|
||||
func (this GlobalParams) Int() int {
|
||||
return cast.ToInt(this.Value())
|
||||
}
|
||||
|
||||
// to uint
|
||||
func (this GlobalParams) Uint() uint {
|
||||
return cast.ToUint(this.Value())
|
||||
}
|
||||
|
||||
// to uint64
|
||||
func (this GlobalParams) Uint64() uint64 {
|
||||
return cast.ToUint64(this.Value())
|
||||
}
|
||||
|
||||
// to uint32
|
||||
func (this GlobalParams) Uint32() uint32 {
|
||||
return cast.ToUint32(this.Value())
|
||||
}
|
||||
|
||||
// to uint16
|
||||
func (this GlobalParams) Uint16() uint16 {
|
||||
return cast.ToUint16(this.Value())
|
||||
}
|
||||
|
||||
// to uint8
|
||||
func (this GlobalParams) Uint8() uint8 {
|
||||
return cast.ToUint8(this.Value())
|
||||
}
|
||||
|
||||
// to string
|
||||
func (this GlobalParams) String() string {
|
||||
return cast.ToString(this.Value())
|
||||
}
|
||||
|
||||
// to map[string]string
|
||||
func (this GlobalParams) StringMapString() map[string]string {
|
||||
return cast.ToStringMapString(this.Value())
|
||||
}
|
||||
|
||||
// to map[string][]string
|
||||
func (this GlobalParams) StringMapStringSlice() map[string][]string {
|
||||
return cast.ToStringMapStringSlice(this.Value())
|
||||
}
|
||||
|
||||
// to map[string]bool
|
||||
func (this GlobalParams) StringMapBool() map[string]bool {
|
||||
return cast.ToStringMapBool(this.Value())
|
||||
}
|
||||
|
||||
// to map[string]int
|
||||
func (this GlobalParams) StringMapInt() map[string]int {
|
||||
return cast.ToStringMapInt(this.Value())
|
||||
}
|
||||
|
||||
// to map[string]int64
|
||||
func (this GlobalParams) StringMapInt64() map[string]int64 {
|
||||
return cast.ToStringMapInt64(this.Value())
|
||||
}
|
||||
|
||||
// to map[string]any
|
||||
func (this GlobalParams) StringMap() map[string]any {
|
||||
return cast.ToStringMap(this.Value())
|
||||
}
|
||||
|
||||
// to []any
|
||||
func (this GlobalParams) Slice() []any {
|
||||
return cast.ToSlice(this.Value())
|
||||
}
|
||||
|
||||
// to []bool
|
||||
func (this GlobalParams) BoolSlice() []bool {
|
||||
return cast.ToBoolSlice(this.Value())
|
||||
}
|
||||
|
||||
// to []string
|
||||
func (this GlobalParams) StringSlice() []string {
|
||||
return cast.ToStringSlice(this.Value())
|
||||
}
|
||||
|
||||
// to []int
|
||||
func (this GlobalParams) IntSlice() []int {
|
||||
return cast.ToIntSlice(this.Value())
|
||||
}
|
||||
|
||||
func NewGlobalParam(data string, user contracts.User) contracts.GlobalParams {
|
||||
return &GlobalParams{user: &user, gjson: gjson.Parse(data)}
|
||||
}
|
||||
@@ -5,34 +5,36 @@ import (
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"git.fsdpf.net/go/condition"
|
||||
"git.fsdpf.net/go/contracts"
|
||||
"git.fsdpf.net/go/db"
|
||||
"git.fsdpf.net/go/utils"
|
||||
"github.com/samber/do"
|
||||
"github.com/samber/lo"
|
||||
"github.com/spf13/cast"
|
||||
)
|
||||
|
||||
type Operation struct {
|
||||
Uuid string `json:"uuid"`
|
||||
Name string `json:"name"`
|
||||
Code string `json:"code"`
|
||||
Icon string `json:"icon"`
|
||||
Size string `json:"size"`
|
||||
Block bool `json:"block"`
|
||||
Ghost bool `json:"ghost"`
|
||||
Shape string `json:"shape"`
|
||||
Type string `json:"type"`
|
||||
PopConfirm any `json:"popConfirm,omitempty"`
|
||||
Widget string `json:"widget"`
|
||||
WidgetType string `json:"widgetType"`
|
||||
WidgetProps any `json:"widgetProps"`
|
||||
WidgetSetting any `json:"widgetSetting"`
|
||||
WidgetContainerSetting any `json:"widgetContainerSetting"`
|
||||
IsRefresh int `json:"isRefresh"`
|
||||
NoAuthType string `json:"noAuthType"`
|
||||
Roles []string `json:"-"`
|
||||
Children []Operation `json:"children,omitempty"`
|
||||
AccessCondition contracts.Condition `json:"-"`
|
||||
Uuid string `json:"uuid"`
|
||||
Name string `json:"name"`
|
||||
Code string `json:"code"`
|
||||
Icon string `json:"icon"`
|
||||
Size string `json:"size"`
|
||||
Block bool `json:"block"`
|
||||
Ghost bool `json:"ghost"`
|
||||
Shape string `json:"shape"`
|
||||
Type string `json:"type"`
|
||||
PopConfirm any `json:"popConfirm,omitempty"`
|
||||
Widget string `json:"widget"`
|
||||
WidgetType string `json:"widgetType"`
|
||||
WidgetProps any `json:"widgetProps"`
|
||||
WidgetSetting any `json:"widgetSetting"`
|
||||
WidgetContainerSetting any `json:"widgetContainerSetting"`
|
||||
IsRefresh int `json:"isRefresh"`
|
||||
NoAuthType string `json:"noAuthType"`
|
||||
Roles []string `json:"-"`
|
||||
Children []Operation `json:"children,omitempty"`
|
||||
AccessCondition *condition.Condition `json:"-"`
|
||||
}
|
||||
|
||||
type OperationAccess struct {
|
||||
@@ -42,14 +44,13 @@ type OperationAccess struct {
|
||||
|
||||
func (o Operation) ToDBColumn(model contracts.Model, container *do.Injector) (column db.Expression, field reflect.StructField) {
|
||||
GetOrmConditionByRes := do.MustInvoke[contracts.GetOrmConditionByRes](container)
|
||||
NewOrmCondition := do.MustInvoke[contracts.NewOrmCondition](container)
|
||||
|
||||
uuid := strings.ReplaceAll(o.Uuid, "-", "_")
|
||||
|
||||
// 主键
|
||||
pk := model.GetCode() + "." + model.GetPrimaryKey()
|
||||
|
||||
cond := lo.Ternary(o.AccessCondition != nil, o.AccessCondition, NewOrmCondition(contracts.ConditionType_AND, "operation access condition "+uuid))
|
||||
cond := lo.Ternary(o.AccessCondition != nil, o.AccessCondition, condition.New(condition.Describe("operation access condition "+uuid)))
|
||||
|
||||
if c := GetOrmConditionByRes(o.Uuid, "operation access condition "+uuid); c.IsNotEmpty() {
|
||||
cond.SetCondition(c)
|
||||
@@ -63,7 +64,7 @@ func (o Operation) ToDBColumn(model contracts.Model, container *do.Injector) (co
|
||||
|
||||
// 主键类型
|
||||
tPkType := reflect.TypeOf("")
|
||||
if tPk, ok := GetStructField(model.GetQueryFieldsStruct(), model.GetPrimaryKey()); ok {
|
||||
if tPk, ok := utils.GetStructField(model.GetQueryFieldsStruct(), model.GetPrimaryKey()); ok {
|
||||
tPkType = tPk.Type
|
||||
}
|
||||
field = reflect.StructField{
|
||||
@@ -149,7 +150,7 @@ func NewOperationAccess(m contracts.Model) OperationAccess {
|
||||
// 主键类型
|
||||
tPkType := reflect.String
|
||||
|
||||
if tPk, ok := GetStructField(m.GetQueryFieldsStruct(), m.GetPrimaryKey()); ok {
|
||||
if tPk, ok := utils.GetStructField(m.GetQueryFieldsStruct(), m.GetPrimaryKey()); ok {
|
||||
switch tPk.Type.Kind() {
|
||||
case reflect.Int, reflect.Int32, reflect.Int64,
|
||||
reflect.Uint, reflect.Uint32, reflect.Uint64:
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"git.fsdpf.net/go/contracts"
|
||||
"git.fsdpf.net/go/req"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
@@ -40,8 +41,8 @@ var wsUpgrader = websocket.Upgrader{
|
||||
},
|
||||
}
|
||||
|
||||
func (this RawResponse) Get(path ...string) contracts.GlobalParams {
|
||||
return lo.Ternary(len(path) == 0, NewGlobalParam(string(this.raw), nil), NewGlobalParam(string(this.raw), nil).Get(strings.Join(path, ".")))
|
||||
func (this RawResponse) Get(path ...string) req.GlobalParams {
|
||||
return lo.Ternary(len(path) == 0, req.NewGlobalParam(string(this.raw), nil), req.NewGlobalParam(string(this.raw), nil).Get(strings.Join(path, ".")))
|
||||
}
|
||||
|
||||
func (this RawResponse) Send(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -54,8 +55,8 @@ func (this RawResponse) Send(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
func (this JsonResponse) Get(path ...string) contracts.GlobalParams {
|
||||
return lo.Ternary(len(path) == 0, NewGlobalParam(string(this.raw), nil), NewGlobalParam(string(this.raw), nil).Get(strings.Join(path, ".")))
|
||||
func (this JsonResponse) Get(path ...string) req.GlobalParams {
|
||||
return lo.Ternary(len(path) == 0, req.NewGlobalParam(string(this.raw), nil), req.NewGlobalParam(string(this.raw), nil).Get(strings.Join(path, ".")))
|
||||
}
|
||||
|
||||
func (this JsonResponse) Send(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -69,12 +70,12 @@ func (this JsonResponse) Send(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
func (this MsgResponse) Get(path ...string) contracts.GlobalParams {
|
||||
func (this MsgResponse) Get(path ...string) req.GlobalParams {
|
||||
if resp, err := json.Marshal(map[string]any{
|
||||
"code": this.code,
|
||||
"msg": this.msg,
|
||||
}); err == nil {
|
||||
return lo.Ternary(len(path) == 0, NewGlobalParam(string(resp), nil), NewGlobalParam(string(resp), nil).Get(strings.Join(path, ".")))
|
||||
return lo.Ternary(len(path) == 0, req.NewGlobalParam(string(resp), nil), req.NewGlobalParam(string(resp), nil).Get(strings.Join(path, ".")))
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -88,13 +89,13 @@ func (this MsgResponse) Send(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
func (this ErrResponse) Get(path ...string) contracts.GlobalParams {
|
||||
func (this ErrResponse) Get(path ...string) req.GlobalParams {
|
||||
if resp, err := json.Marshal(map[string]any{
|
||||
"code": this.code,
|
||||
"msg": this.msg,
|
||||
"error": string(this.stack),
|
||||
}); err == nil {
|
||||
return lo.Ternary(len(path) == 0, NewGlobalParam(string(resp), nil), NewGlobalParam(string(resp), nil).Get(strings.Join(path, ".")))
|
||||
return lo.Ternary(len(path) == 0, req.NewGlobalParam(string(resp), nil), req.NewGlobalParam(string(resp), nil).Get(strings.Join(path, ".")))
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -108,12 +109,12 @@ func (this ErrResponse) Send(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
func (this FileResponse) Get(path ...string) contracts.GlobalParams {
|
||||
func (this FileResponse) Get(path ...string) req.GlobalParams {
|
||||
if resp, err := json.Marshal(map[string]any{
|
||||
"name": this.name,
|
||||
"disposition": this.disposition,
|
||||
}); err == nil {
|
||||
return lo.Ternary(len(path) == 0, NewGlobalParam(string(resp), nil), NewGlobalParam(string(resp), nil).Get(strings.Join(path, ".")))
|
||||
return lo.Ternary(len(path) == 0, req.NewGlobalParam(string(resp), nil), req.NewGlobalParam(string(resp), nil).Get(strings.Join(path, ".")))
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -130,31 +131,31 @@ func (this FileResponse) Send(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
func NewRawResponse(b []byte) contracts.HttpResponse {
|
||||
func NewRawResponse(b []byte) req.HttpResponse {
|
||||
return &RawResponse{raw: b}
|
||||
}
|
||||
|
||||
func NewJsonResponse(b []byte) contracts.HttpResponse {
|
||||
func NewJsonResponse(b []byte) req.HttpResponse {
|
||||
return &JsonResponse{raw: b}
|
||||
}
|
||||
|
||||
func NewFileResponse(name string, disposition string) contracts.HttpResponse {
|
||||
func NewFileResponse(name string, disposition string) req.HttpResponse {
|
||||
return &FileResponse{name: name, disposition: disposition}
|
||||
}
|
||||
|
||||
func NewMsgResponse(msg string, code int) contracts.HttpResponse {
|
||||
func NewMsgResponse(msg string, code int) req.HttpResponse {
|
||||
return &MsgResponse{msg: msg, code: code}
|
||||
}
|
||||
|
||||
func NewErrResponse(err *contracts.Err) contracts.HttpResponse {
|
||||
func NewErrResponse(err *contracts.Err) req.HttpResponse {
|
||||
return NewJsonResponse([]byte(fmt.Sprintf(`{"code": %d, "msg": %q}`, err.Code, err.Error())))
|
||||
}
|
||||
|
||||
func HttpResponse(data any) contracts.HttpResponse {
|
||||
func HttpResponse(data any) req.HttpResponse {
|
||||
var err error
|
||||
// fmt.Printf("%#v \n", data)
|
||||
switch v := data.(type) {
|
||||
case contracts.HttpResponse:
|
||||
case req.HttpResponse:
|
||||
return v
|
||||
case contracts.Errno:
|
||||
return NewMsgResponse(v.Error(), v.Code)
|
||||
|
||||
175
support/util.go
175
support/util.go
@@ -1,175 +0,0 @@
|
||||
package support
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"github.com/spf13/cast"
|
||||
)
|
||||
|
||||
func GetFieldValue(i any, k string) any {
|
||||
v := reflect.ValueOf(i)
|
||||
|
||||
var kv reflect.Value
|
||||
|
||||
if v.Kind() == reflect.Ptr {
|
||||
v = reflect.Indirect(v)
|
||||
}
|
||||
|
||||
if v.Kind() == reflect.Struct {
|
||||
kv = v.FieldByName(k)
|
||||
} else if v.Kind() == reflect.Map {
|
||||
for _, key := range v.MapKeys() {
|
||||
if key.String() == k {
|
||||
kv = v.MapIndex(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch kv.Kind() {
|
||||
case reflect.String:
|
||||
return kv.String()
|
||||
case reflect.Bool:
|
||||
return kv.Bool()
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return kv.Float()
|
||||
case reflect.Int, reflect.Int64:
|
||||
return int(kv.Int())
|
||||
case reflect.Invalid:
|
||||
return nil
|
||||
}
|
||||
|
||||
return kv.Interface()
|
||||
}
|
||||
|
||||
func GetStructField(item any, key string) (field reflect.StructField, ok bool) {
|
||||
vItem := reflect.TypeOf(item)
|
||||
|
||||
if vItem.Kind() == reflect.Ptr {
|
||||
vItem = vItem.Elem()
|
||||
}
|
||||
|
||||
if vItem.Kind() != reflect.Struct {
|
||||
return field, false
|
||||
}
|
||||
|
||||
return vItem.FieldByName(UcFirst(key))
|
||||
}
|
||||
|
||||
func InterfaceToSlice(i any) (ret []any) {
|
||||
rv := reflect.ValueOf(i)
|
||||
|
||||
if rv.Kind() == reflect.Ptr {
|
||||
rv = reflect.Indirect(rv)
|
||||
}
|
||||
|
||||
if rv.Kind() != reflect.Slice {
|
||||
panic("请传入切片类型数据")
|
||||
}
|
||||
|
||||
for i := 0; i < rv.Len(); i++ {
|
||||
ret = append(ret, rv.Index(i).Interface())
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func SliceConvert(origSlice any, newSliceType reflect.Type) any {
|
||||
sv := reflect.ValueOf(origSlice)
|
||||
|
||||
if sv.Kind() != reflect.Slice {
|
||||
panic(fmt.Sprintf("无效切片类型 %T (来源)", origSlice))
|
||||
}
|
||||
|
||||
if newSliceType.Kind() != reflect.Slice {
|
||||
panic(fmt.Sprintf("无效切片类型 %T (目标)", newSliceType))
|
||||
}
|
||||
|
||||
// 生成新类型的切片
|
||||
newSlice := reflect.New(newSliceType)
|
||||
|
||||
// hdr指向到新生成切片的SliceHeader
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(newSlice.Pointer()))
|
||||
|
||||
var newElemSize = int(sv.Type().Elem().Size()) / int(newSliceType.Elem().Size())
|
||||
|
||||
// 设置SliceHeader的Cap,Len,以及数组的ptr
|
||||
hdr.Cap = sv.Cap() * newElemSize
|
||||
hdr.Len = sv.Len() * newElemSize
|
||||
hdr.Data = uintptr(sv.Pointer())
|
||||
|
||||
return newSlice.Elem().Interface()
|
||||
}
|
||||
|
||||
func DeepSearch(m map[string]any, path []string) map[string]any {
|
||||
for _, k := range path {
|
||||
m2, ok := m[k]
|
||||
if !ok {
|
||||
// intermediate key does not exist
|
||||
// => create it and continue from there
|
||||
m3 := make(map[string]interface{})
|
||||
m[k] = m3
|
||||
m = m3
|
||||
continue
|
||||
}
|
||||
m3, ok := m2.(map[string]interface{})
|
||||
if !ok {
|
||||
// intermediate key is a value
|
||||
// => replace with a new map
|
||||
m3 = make(map[string]interface{})
|
||||
m[k] = m3
|
||||
}
|
||||
// continue search from here
|
||||
m = m3
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func MergeMap(shadow map[string]any, m map[string]any) map[string]any {
|
||||
if shadow == nil {
|
||||
shadow = make(map[string]any)
|
||||
}
|
||||
|
||||
var m2 map[string]any
|
||||
|
||||
for k, val := range m {
|
||||
switch val.(type) {
|
||||
case map[string]any:
|
||||
m2 = val.(map[string]any)
|
||||
case map[any]any:
|
||||
m2 = cast.ToStringMap(val)
|
||||
default:
|
||||
// immediate value
|
||||
shadow[k] = val
|
||||
continue
|
||||
}
|
||||
// recursively merge to shadow map
|
||||
shadow[k] = MergeMap(cast.ToStringMap(shadow[k]), m2)
|
||||
}
|
||||
return shadow
|
||||
}
|
||||
|
||||
func UcFirst(s string) string {
|
||||
if s == "" {
|
||||
return ""
|
||||
}
|
||||
return strings.ToUpper(s[:1]) + s[1:]
|
||||
}
|
||||
|
||||
func StudlyCase(s string) string {
|
||||
return strings.Replace(strings.Title(strings.Replace(s, "-", " ", -1)), " ", "", -1)
|
||||
}
|
||||
|
||||
func GetAbsPath(s string) string {
|
||||
if strings.HasPrefix(s, "/") {
|
||||
return s
|
||||
} else if dir, err := os.Getwd(); err == nil {
|
||||
return filepath.Join(dir, s)
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package support
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDeepSearch(t *testing.T) {
|
||||
m := map[string]any{
|
||||
"a": 1,
|
||||
"b": map[string]any{
|
||||
"c": 2,
|
||||
},
|
||||
}
|
||||
|
||||
mb := DeepSearch(m, []string{"b", "a"})
|
||||
|
||||
t.Log(m)
|
||||
|
||||
mb["cc"] = "3"
|
||||
|
||||
t.Log(m)
|
||||
}
|
||||
|
||||
func TestMergeMap(t *testing.T) {
|
||||
m1 := map[string]any{
|
||||
"a": 1,
|
||||
"b": map[string]any{
|
||||
"c": 2,
|
||||
"a": 1,
|
||||
"b": map[string]any{
|
||||
"c": 2,
|
||||
"a": 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
m2 := map[string]any{
|
||||
"a": 11,
|
||||
"b": map[string]any{
|
||||
"c": 22,
|
||||
"cc": 33,
|
||||
},
|
||||
}
|
||||
|
||||
t.Log(MergeMap(m1, m2))
|
||||
}
|
||||
Reference in New Issue
Block a user