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/internal/api/jssdk/tools.go

78 lines
1.7 KiB

package jssdk
import (
"context"
"github.com/gin-gonic/gin"
"github.com/openimsdk/tools/a2r"
"github.com/openimsdk/tools/apiresp"
"github.com/openimsdk/tools/checker"
"github.com/openimsdk/tools/errs"
"google.golang.org/grpc"
"google.golang.org/protobuf/proto"
"io"
"strings"
)
func field[A, B, C any](ctx context.Context, fn func(ctx context.Context, req *A, opts ...grpc.CallOption) (*B, error), req *A, get func(*B) C) (C, error) {
resp, err := fn(ctx, req)
if err != nil {
var c C
return c, err
}
return get(resp), nil
}
func call[A, B any](c *gin.Context, fn func(ctx context.Context, req *A) (*B, error)) {
var isJSON bool
switch contentType := c.GetHeader("Content-Type"); {
case contentType == "":
isJSON = true
case strings.Contains(contentType, "application/json"):
isJSON = true
case strings.Contains(contentType, "application/protobuf"):
case strings.Contains(contentType, "application/x-protobuf"):
default:
apiresp.GinError(c, errs.ErrArgs.WrapMsg("unsupported content type"))
return
}
var req *A
if isJSON {
var err error
req, err = a2r.ParseRequest[A](c)
if err != nil {
apiresp.GinError(c, err)
return
}
} else {
body, err := io.ReadAll(c.Request.Body)
if err != nil {
apiresp.GinError(c, err)
return
}
req = new(A)
if err := proto.Unmarshal(body, any(req).(proto.Message)); err != nil {
apiresp.GinError(c, err)
return
}
if err := checker.Validate(&req); err != nil {
apiresp.GinError(c, err)
return
}
}
resp, err := fn(c, req)
if err != nil {
apiresp.GinError(c, err)
return
}
if isJSON {
apiresp.GinSuccess(c, resp)
return
}
body, err := proto.Marshal(any(resp).(proto.Message))
if err != nil {
apiresp.GinError(c, err)
return
}
apiresp.GinSuccess(c, body)
}