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) }