Go generics and changes in v1.18 (#5)

* ArrayIn to use generics.

* interface{} -> any.
This commit is contained in:
Miroslav Šedivý 2022-07-28 12:20:20 +02:00 committed by GitHub
parent c725e96c90
commit babddacbf3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 100 additions and 110 deletions

View File

@ -46,7 +46,7 @@ func (h *RoomHandler) boradcastStart(w http.ResponseWriter, r *http.Request) err
message.BroadcastStatus{
IsActive: broadcast.Started(),
URL: broadcast.Url(),
}, nil)
})
return utils.HttpSuccess(w)
}
@ -64,7 +64,7 @@ func (h *RoomHandler) boradcastStop(w http.ResponseWriter, r *http.Request) erro
message.BroadcastStatus{
IsActive: broadcast.Started(),
URL: broadcast.Url(),
}, nil)
})
return utils.HttpSuccess(w)
}

View File

@ -40,7 +40,7 @@ func (h *RoomHandler) screenConfigurationChange(w http.ResponseWriter, r *http.R
}
payload := message.ScreenSize(*data)
h.sessions.Broadcast(event.SCREEN_UPDATED, payload, nil)
h.sessions.Broadcast(event.SCREEN_UPDATED, payload)
return utils.HttpSuccess(w, data)
}

View File

@ -67,7 +67,7 @@ func (manager *DesktopManagerCtx) ClipboardSetBinary(mime string, data []byte) e
// TODO: Refactor.
// We need to wait until the data came to the clipboard.
wait := make(chan struct{})
xevent.Emmiter.Once("clipboard-updated", func(payload ...interface{}) {
xevent.Emmiter.Once("clipboard-updated", func(payload ...any) {
wait <- struct{}{}
})

View File

@ -18,20 +18,20 @@ func (manager *DesktopManagerCtx) DropFiles(x int, y int, files []string) bool {
drop.Emmiter.Clear()
drop.Emmiter.Once("create", func(payload ...interface{}) {
drop.Emmiter.Once("create", func(payload ...any) {
manager.Move(0, 0)
})
drop.Emmiter.Once("cursor-enter", func(payload ...interface{}) {
drop.Emmiter.Once("cursor-enter", func(payload ...any) {
//nolint
manager.ButtonDown(1)
})
drop.Emmiter.Once("button-press", func(payload ...interface{}) {
drop.Emmiter.Once("button-press", func(payload ...any) {
manager.Move(x, y)
})
drop.Emmiter.Once("begin", func(payload ...interface{}) {
drop.Emmiter.Once("begin", func(payload ...any) {
for i := 0; i < dropMoveRepeat; i++ {
manager.Move(x, y)
time.Sleep(dropMoveDelay)
@ -42,7 +42,7 @@ func (manager *DesktopManagerCtx) DropFiles(x int, y int, files []string) bool {
})
finished := make(chan bool)
drop.Emmiter.Once("finish", func(payload ...interface{}) {
drop.Emmiter.Once("finish", func(payload ...any) {
finished <- payload[0].(bool)
})

View File

@ -79,13 +79,13 @@ func (manager *DesktopManagerCtx) Start() {
}
func (manager *DesktopManagerCtx) OnBeforeScreenSizeChange(listener func()) {
manager.emmiter.On("before_screen_size_change", func(payload ...interface{}) {
manager.emmiter.On("before_screen_size_change", func(payload ...any) {
listener()
})
}
func (manager *DesktopManagerCtx) OnAfterScreenSizeChange(listener func()) {
manager.emmiter.On("after_screen_size_change", func(payload ...interface{}) {
manager.emmiter.On("after_screen_size_change", func(payload ...any) {
listener()
})
}

View File

@ -5,31 +5,31 @@ import (
)
func (manager *DesktopManagerCtx) OnCursorChanged(listener func(serial uint64)) {
xevent.Emmiter.On("cursor-changed", func(payload ...interface{}) {
xevent.Emmiter.On("cursor-changed", func(payload ...any) {
listener(payload[0].(uint64))
})
}
func (manager *DesktopManagerCtx) OnClipboardUpdated(listener func()) {
xevent.Emmiter.On("clipboard-updated", func(payload ...interface{}) {
xevent.Emmiter.On("clipboard-updated", func(payload ...any) {
listener()
})
}
func (manager *DesktopManagerCtx) OnFileChooserDialogOpened(listener func()) {
xevent.Emmiter.On("file-chooser-dialog-opened", func(payload ...interface{}) {
xevent.Emmiter.On("file-chooser-dialog-opened", func(payload ...any) {
listener()
})
}
func (manager *DesktopManagerCtx) OnFileChooserDialogClosed(listener func()) {
xevent.Emmiter.On("file-chooser-dialog-closed", func(payload ...interface{}) {
xevent.Emmiter.On("file-chooser-dialog-closed", func(payload ...any) {
listener()
})
}
func (manager *DesktopManagerCtx) OnEventError(listener func(error_code uint8, message string, request_code uint8, minor_code uint8)) {
xevent.Emmiter.On("event-error", func(payload ...interface{}) {
xevent.Emmiter.On("event-error", func(payload ...any) {
listener(payload[0].(uint8), payload[1].(string), payload[2].(uint8), payload[3].(uint8))
})
}

View File

@ -22,7 +22,7 @@ func (l *logFormatter) NewLogEntry(r *http.Request) middleware.LogEntry {
return &nulllog{}
}
req := map[string]interface{}{}
req := map[string]any{}
if reqID := middleware.GetReqID(r.Context()); reqID != "" {
req["id"] = reqID
@ -57,7 +57,7 @@ type logPanic struct {
stack string
}
func (e *logEntry) Panic(v interface{}, stack []byte) {
func (e *logEntry) Panic(v any, stack []byte) {
e.panic = &logPanic{
message: fmt.Sprintf("%+v", v),
stack: string(stack),
@ -72,8 +72,8 @@ func (e *logEntry) SetSession(session types.Session) {
e.session = &session
}
func (e *logEntry) Write(status, bytes int, header http.Header, elapsed time.Duration, extra interface{}) {
res := map[string]interface{}{}
func (e *logEntry) Write(status, bytes int, header http.Header, elapsed time.Duration, extra any) {
res := map[string]any{}
res["time"] = time.Now().UTC().Format(time.RFC1123)
res["status"] = status
res["bytes"] = bytes
@ -128,8 +128,8 @@ func (e *logEntry) Write(status, bytes int, header http.Header, elapsed time.Dur
type nulllog struct{}
func (e *nulllog) Panic(v interface{}, stack []byte) {}
func (e *nulllog) Error(err error) {}
func (e *nulllog) SetSession(session types.Session) {}
func (e *nulllog) Write(status, bytes int, header http.Header, elapsed time.Duration, extra interface{}) {
func (e *nulllog) Panic(v any, stack []byte) {}
func (e *nulllog) Error(err error) {}
func (e *nulllog) SetSession(session types.Session) {}
func (e *nulllog) Write(status, bytes int, header http.Header, elapsed time.Duration, extra any) {
}

View File

@ -237,13 +237,13 @@ func (manager *SessionManagerCtx) PopCursors() map[types.Session][]types.Cursor
// broadcasts
// ---
func (manager *SessionManagerCtx) Broadcast(event string, payload interface{}, exclude interface{}) {
func (manager *SessionManagerCtx) Broadcast(event string, payload any, exclude ...string) {
for _, session := range manager.List() {
if !session.State().IsConnected {
continue
}
if exclude != nil {
if len(exclude) > 0 {
if in, _ := utils.ArrayIn(session.ID(), exclude); in {
continue
}
@ -253,13 +253,13 @@ func (manager *SessionManagerCtx) Broadcast(event string, payload interface{}, e
}
}
func (manager *SessionManagerCtx) AdminBroadcast(event string, payload interface{}, exclude interface{}) {
func (manager *SessionManagerCtx) AdminBroadcast(event string, payload any, exclude ...string) {
for _, session := range manager.List() {
if !session.State().IsConnected || !session.Profile().IsAdmin {
continue
}
if exclude != nil {
if len(exclude) > 0 {
if in, _ := utils.ArrayIn(session.ID(), exclude); in {
continue
}
@ -269,13 +269,13 @@ func (manager *SessionManagerCtx) AdminBroadcast(event string, payload interface
}
}
func (manager *SessionManagerCtx) InactiveCursorsBroadcast(event string, payload interface{}, exclude interface{}) {
func (manager *SessionManagerCtx) InactiveCursorsBroadcast(event string, payload any, exclude ...string) {
for _, session := range manager.List() {
if !session.State().IsConnected || !session.Profile().CanSeeInactiveCursors {
continue
}
if exclude != nil {
if len(exclude) > 0 {
if in, _ := utils.ArrayIn(session.ID(), exclude); in {
continue
}
@ -290,43 +290,43 @@ func (manager *SessionManagerCtx) InactiveCursorsBroadcast(event string, payload
// ---
func (manager *SessionManagerCtx) OnCreated(listener func(session types.Session)) {
manager.emmiter.On("created", func(payload ...interface{}) {
manager.emmiter.On("created", func(payload ...any) {
listener(payload[0].(*SessionCtx))
})
}
func (manager *SessionManagerCtx) OnDeleted(listener func(session types.Session)) {
manager.emmiter.On("deleted", func(payload ...interface{}) {
manager.emmiter.On("deleted", func(payload ...any) {
listener(payload[0].(*SessionCtx))
})
}
func (manager *SessionManagerCtx) OnConnected(listener func(session types.Session)) {
manager.emmiter.On("connected", func(payload ...interface{}) {
manager.emmiter.On("connected", func(payload ...any) {
listener(payload[0].(*SessionCtx))
})
}
func (manager *SessionManagerCtx) OnDisconnected(listener func(session types.Session)) {
manager.emmiter.On("disconnected", func(payload ...interface{}) {
manager.emmiter.On("disconnected", func(payload ...any) {
listener(payload[0].(*SessionCtx))
})
}
func (manager *SessionManagerCtx) OnProfileChanged(listener func(session types.Session)) {
manager.emmiter.On("profile_changed", func(payload ...interface{}) {
manager.emmiter.On("profile_changed", func(payload ...any) {
listener(payload[0].(*SessionCtx))
})
}
func (manager *SessionManagerCtx) OnStateChanged(listener func(session types.Session)) {
manager.emmiter.On("state_changed", func(payload ...interface{}) {
manager.emmiter.On("state_changed", func(payload ...any) {
listener(payload[0].(*SessionCtx))
})
}
func (manager *SessionManagerCtx) OnHostChanged(listener func(session types.Session)) {
manager.emmiter.On("host_changed", func(payload ...interface{}) {
manager.emmiter.On("host_changed", func(payload ...any) {
if payload[0] == nil {
listener(nil)
} else {
@ -336,7 +336,7 @@ func (manager *SessionManagerCtx) OnHostChanged(listener func(session types.Sess
}
func (manager *SessionManagerCtx) OnSettingsChanged(listener func(new types.Settings, old types.Settings)) {
manager.emmiter.On("settings_changed", func(payload ...interface{}) {
manager.emmiter.On("settings_changed", func(payload ...any) {
listener(payload[0].(types.Settings), payload[1].(types.Settings))
})
}

View File

@ -119,7 +119,7 @@ func (session *SessionCtx) GetWebSocketPeer() types.WebSocketPeer {
return session.websocketPeer
}
func (session *SessionCtx) Send(event string, payload interface{}) {
func (session *SessionCtx) Send(event string, payload any) {
peer := session.GetWebSocketPeer()
if peer != nil {
peer.Send(event, payload)

View File

@ -83,7 +83,7 @@ func (manager *WebRTCManagerCtx) peerConfiguration() webrtc.Configuration {
ICEServers := []webrtc.ICEServer{}
for _, server := range manager.config.ICEServers {
var credential interface{}
var credential any
if server.Credential != "" {
credential = server.Credential
} else {

View File

@ -16,7 +16,7 @@ func (l logger) Trace(msg string) {
l.logger.Trace().Msg(strings.TrimSpace(msg))
}
func (l logger) Tracef(format string, args ...interface{}) {
func (l logger) Tracef(format string, args ...any) {
msg := fmt.Sprintf(format, args...)
l.logger.Trace().Msg(strings.TrimSpace(msg))
}
@ -25,7 +25,7 @@ func (l logger) Debug(msg string) {
l.logger.Debug().Msg(strings.TrimSpace(msg))
}
func (l logger) Debugf(format string, args ...interface{}) {
func (l logger) Debugf(format string, args ...any) {
msg := fmt.Sprintf(format, args...)
l.logger.Debug().Msg(strings.TrimSpace(msg))
}
@ -38,7 +38,7 @@ func (l logger) Info(msg string) {
l.logger.Info().Msg(strings.TrimSpace(msg))
}
func (l logger) Infof(format string, args ...interface{}) {
func (l logger) Infof(format string, args ...any) {
msg := fmt.Sprintf(format, args...)
if strings.Contains(msg, "duplicated packet") {
return
@ -51,7 +51,7 @@ func (l logger) Warn(msg string) {
l.logger.Warn().Msg(strings.TrimSpace(msg))
}
func (l logger) Warnf(format string, args ...interface{}) {
func (l logger) Warnf(format string, args ...any) {
msg := fmt.Sprintf(format, args...)
l.logger.Warn().Msg(strings.TrimSpace(msg))
}
@ -60,7 +60,7 @@ func (l logger) Error(msg string) {
l.logger.Error().Msg(strings.TrimSpace(msg))
}
func (l logger) Errorf(format string, args ...interface{}) {
func (l logger) Errorf(format string, args ...any) {
msg := fmt.Sprintf(format, args...)
l.logger.Error().Msg(strings.TrimSpace(msg))
}

View File

@ -2,13 +2,13 @@ package pionlog
type nulllog struct{}
func (l nulllog) Trace(msg string) {}
func (l nulllog) Tracef(format string, args ...interface{}) {}
func (l nulllog) Debug(msg string) {}
func (l nulllog) Debugf(format string, args ...interface{}) {}
func (l nulllog) Info(msg string) {}
func (l nulllog) Infof(format string, args ...interface{}) {}
func (l nulllog) Warn(msg string) {}
func (l nulllog) Warnf(format string, args ...interface{}) {}
func (l nulllog) Error(msg string) {}
func (l nulllog) Errorf(format string, args ...interface{}) {}
func (l nulllog) Trace(msg string) {}
func (l nulllog) Tracef(format string, args ...any) {}
func (l nulllog) Debug(msg string) {}
func (l nulllog) Debugf(format string, args ...any) {}
func (l nulllog) Info(msg string) {}
func (l nulllog) Infof(format string, args ...any) {}
func (l nulllog) Warn(msg string) {}
func (l nulllog) Warnf(format string, args ...any) {}
func (l nulllog) Error(msg string) {}
func (l nulllog) Errorf(format string, args ...any) {}

View File

@ -26,7 +26,7 @@ func (manager *WebSocketManagerCtx) fileChooserDialogEvents() {
event.FILE_CHOOSER_DIALOG_OPENED,
message.SessionID{
ID: host.ID(),
}, nil)
})
})
// when dialog closes, everyone should be notified.
@ -37,7 +37,7 @@ func (manager *WebSocketManagerCtx) fileChooserDialogEvents() {
go manager.sessions.Broadcast(
event.FILE_CHOOSER_DIALOG_CLOSED,
message.SessionID{}, nil)
message.SessionID{})
})
// when new user joins, and someone holds dialog, he shouldd be notified about it.

View File

@ -18,6 +18,6 @@ func (h *MessageHandlerCtx) screenSet(session types.Session, payload *message.Sc
return err
}
h.sessions.Broadcast(event.SCREEN_UPDATED, payload, nil)
h.sessions.Broadcast(event.SCREEN_UPDATED, payload)
return nil
}

View File

@ -33,7 +33,7 @@ func (h *MessageHandlerCtx) sendBroadcast(session types.Session, payload *messag
Sender: session.ID(),
Subject: payload.Subject,
Body: payload.Body,
}, []string{session.ID()})
}, session.ID())
return nil
}

View File

@ -13,7 +13,7 @@ func (h *MessageHandlerCtx) SessionCreated(session types.Session) error {
ID: session.ID(),
Profile: session.Profile(),
State: session.State(),
}, nil)
})
return nil
}
@ -23,7 +23,7 @@ func (h *MessageHandlerCtx) SessionDeleted(session types.Session) error {
event.SESSION_DELETED,
message.SessionID{
ID: session.ID(),
}, nil)
})
return nil
}
@ -58,7 +58,7 @@ func (h *MessageHandlerCtx) SessionProfileChanged(session types.Session) error {
message.MemberProfile{
ID: session.ID(),
MemberProfile: session.Profile(),
}, nil)
})
return nil
}
@ -69,7 +69,7 @@ func (h *MessageHandlerCtx) SessionStateChanged(session types.Session) error {
message.SessionState{
ID: session.ID(),
SessionState: session.State(),
}, nil)
})
return nil
}

View File

@ -105,7 +105,7 @@ func (manager *WebSocketManagerCtx) Start() {
payload.HostID = session.ID()
}
manager.sessions.Broadcast(event.CONTROL_HOST, payload, nil)
manager.sessions.Broadcast(event.CONTROL_HOST, payload)
manager.logger.Info().
Bool("has_host", payload.HasHost).
@ -124,7 +124,7 @@ func (manager *WebSocketManagerCtx) Start() {
manager.stopInactiveCursors()
}
manager.sessions.Broadcast(event.SYSTEM_SETTINGS, new, nil)
manager.sessions.Broadcast(event.SYSTEM_SETTINGS, new)
manager.logger.Info().
Interface("new", new).
Interface("old", old).
@ -347,7 +347,7 @@ func (manager *WebSocketManagerCtx) startInactiveCursors() {
// remove last cursor entries and send empty message
_ = manager.sessions.PopCursors()
manager.sessions.InactiveCursorsBroadcast(event.SESSION_CURSORS, []message.SessionCursors{}, nil)
manager.sessions.InactiveCursorsBroadcast(event.SESSION_CURSORS, []message.SessionCursors{})
return
case <-ticker.C:
cursorsMap := manager.sessions.PopCursors()
@ -369,7 +369,7 @@ func (manager *WebSocketManagerCtx) startInactiveCursors() {
)
}
manager.sessions.InactiveCursorsBroadcast(event.SESSION_CURSORS, sessionCursors, nil)
manager.sessions.InactiveCursorsBroadcast(event.SESSION_CURSORS, sessionCursors)
}
}
}()

View File

@ -36,7 +36,7 @@ func (peer *WebSocketPeerCtx) setSessionID(sessionId string) {
peer.logger = peer.logger.With().Str("session_id", sessionId).Logger()
}
func (peer *WebSocketPeerCtx) Send(event string, payload interface{}) {
func (peer *WebSocketPeerCtx) Send(event string, payload any) {
peer.mu.Lock()
defer peer.mu.Unlock()

View File

@ -79,14 +79,14 @@ type VideoConfig struct {
}
func (config *VideoConfig) GetPipeline(screen ScreenSize) (string, error) {
values := map[string]interface{}{
values := map[string]any{
"width": screen.Width,
"height": screen.Height,
"fps": screen.Rate,
}
language := []gval.Language{
gval.Function("round", func(args ...interface{}) (interface{}, error) {
gval.Function("round", func(args ...any) (any, error) {
return (int)(math.Round(args[0].(float64))), nil
}),
}

View File

@ -32,9 +32,9 @@ type SystemAdmin struct {
type SystemLogs = []SystemLog
type SystemLog struct {
Level string `json:"level"`
Fields map[string]interface{} `json:"fields"`
Message string `json:"message"`
Level string `json:"level"`
Fields map[string]any `json:"fields"`
Message string `json:"message"`
}
type SystemDisconnect struct {
@ -163,14 +163,14 @@ type BroadcastStatus struct {
/////////////////////////////
type SendUnicast struct {
Sender string `json:"sender"`
Receiver string `json:"receiver"`
Subject string `json:"subject"`
Body interface{} `json:"body"`
Sender string `json:"sender"`
Receiver string `json:"receiver"`
Subject string `json:"subject"`
Body any `json:"body"`
}
type SendBroadcast struct {
Sender string `json:"sender"`
Subject string `json:"subject"`
Body interface{} `json:"body"`
Sender string `json:"sender"`
Subject string `json:"subject"`
Body any `json:"body"`
}

View File

@ -43,7 +43,7 @@ type Session interface {
SetWebSocketPeer(websocketPeer WebSocketPeer)
SetWebSocketConnected(websocketPeer WebSocketPeer, connected bool)
GetWebSocketPeer() WebSocketPeer
Send(event string, payload interface{})
Send(event string, payload any)
// webrtc
SetWebRTCPeer(webrtcPeer WebRTCPeer)
@ -66,9 +66,9 @@ type SessionManager interface {
SetCursor(cursor Cursor, session Session)
PopCursors() map[Session][]Cursor
Broadcast(event string, payload interface{}, exclude interface{})
AdminBroadcast(event string, payload interface{}, exclude interface{})
InactiveCursorsBroadcast(event string, payload interface{}, exclude interface{})
Broadcast(event string, payload any, exclude ...string)
AdminBroadcast(event string, payload any, exclude ...string)
InactiveCursorsBroadcast(event string, payload any, exclude ...string)
OnCreated(listener func(session Session))
OnDeleted(listener func(session Session))

View File

@ -15,7 +15,7 @@ type WebSocketHandler func(Session, WebSocketMessage) bool
type CheckOrigin func(r *http.Request) bool
type WebSocketPeer interface {
Send(event string, payload interface{})
Send(event string, payload any)
Ping() error
Destroy(reason string)
}

View File

@ -1,22 +1,12 @@
package utils
import (
"reflect"
)
func ArrayIn[T comparable](val T, array []T) (exists bool, index int) {
exists, index = false, -1
func ArrayIn(val interface{}, array interface{}) (exists bool, index int) {
exists = false
index = -1
switch reflect.TypeOf(array).Kind() {
case reflect.Slice:
s := reflect.ValueOf(array)
for i := 0; i < s.Len(); i++ {
if reflect.DeepEqual(val, s.Index(i).Interface()) {
index = i
exists = true
return
}
for i, a := range array {
if a == val {
exists, index = true, i
return
}
}

View File

@ -29,6 +29,6 @@ func Color(str string) string {
return result + str[lastIndex:]
}
func Colorf(format string, a ...interface{}) string {
func Colorf(format string, a ...any) string {
return fmt.Sprintf(Color(format), a...)
}

View File

@ -9,7 +9,7 @@ import (
"github.com/rs/zerolog/log"
)
func HttpJsonRequest(w http.ResponseWriter, r *http.Request, res interface{}) error {
func HttpJsonRequest(w http.ResponseWriter, r *http.Request, res any) error {
err := json.NewDecoder(r.Body).Decode(res)
if err == nil {
@ -23,7 +23,7 @@ func HttpJsonRequest(w http.ResponseWriter, r *http.Request, res interface{}) er
return HttpBadRequest("unable to parse provided data").WithInternalErr(err)
}
func HttpJsonResponse(w http.ResponseWriter, code int, res interface{}) {
func HttpJsonResponse(w http.ResponseWriter, code int, res any) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(code)
@ -32,7 +32,7 @@ func HttpJsonResponse(w http.ResponseWriter, code int, res interface{}) {
}
}
func HttpSuccess(w http.ResponseWriter, res ...interface{}) error {
func HttpSuccess(w http.ResponseWriter, res ...any) error {
if len(res) == 0 {
w.WriteHeader(http.StatusNoContent)
} else {
@ -78,13 +78,13 @@ func (e *HTTPError) WithInternalMsg(msg string) *HTTPError {
}
// WithInternalMsg adds internal formated message information to the error
func (e *HTTPError) WithInternalMsgf(fmtStr string, args ...interface{}) *HTTPError {
func (e *HTTPError) WithInternalMsgf(fmtStr string, args ...any) *HTTPError {
e.InternalMsg = fmt.Sprintf(fmtStr, args...)
return e
}
// Sends error with custom formated message
func (e *HTTPError) Msgf(fmtSt string, args ...interface{}) *HTTPError {
func (e *HTTPError) Msgf(fmtSt string, args ...any) *HTTPError {
e.Message = fmt.Sprintf(fmtSt, args...)
return e
}

View File

@ -5,15 +5,15 @@ import (
"reflect"
)
func Unmarshal(in interface{}, raw []byte, callback func() error) error {
func Unmarshal(in any, raw []byte, callback func() error) error {
if err := json.Unmarshal(raw, &in); err != nil {
return err
}
return callback()
}
func JsonStringAutoDecode(m interface{}) func(rf reflect.Kind, rt reflect.Kind, data interface{}) (interface{}, error) {
return func(rf reflect.Kind, rt reflect.Kind, data interface{}) (interface{}, error) {
func JsonStringAutoDecode(m any) func(rf reflect.Kind, rt reflect.Kind, data any) (any, error) {
return func(rf reflect.Kind, rt reflect.Kind, data any) (any, error) {
if rf != reflect.String || rt == reflect.String {
return data, nil
}