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.
115 lines
2.7 KiB
115 lines
2.7 KiB
package api2rpc
|
|
|
|
import (
|
|
"context"
|
|
"google.golang.org/grpc"
|
|
"reflect"
|
|
)
|
|
|
|
var nameMap = map[string]string{}
|
|
|
|
func getName[T any]() string {
|
|
var t T
|
|
return reflect.TypeOf(&t).Elem().Name()
|
|
}
|
|
|
|
// NewRpc A: apiReq B: apiResp C: rpcReq D: rpcResp Z: rpcClient (group.GroupClient)
|
|
func NewRpc[A, B any, C, D any, Z any](bind ApiBind[A, B], client func(conn *grpc.ClientConn) Z, rpc func(client Z, ctx context.Context, req *C, options ...grpc.CallOption) (*D, error)) *RpcXXXX[A, B, C, D, Z] {
|
|
return &RpcXXXX[A, B, C, D, Z]{
|
|
bind: bind,
|
|
client: client,
|
|
rpc: rpc,
|
|
}
|
|
}
|
|
|
|
type RpcXXXX[A, B any, C, D any, Z any] struct {
|
|
bind ApiBind[A, B]
|
|
name string
|
|
client func(conn *grpc.ClientConn) Z
|
|
rpc func(client Z, ctx context.Context, req *C, options ...grpc.CallOption) (*D, error)
|
|
before func(apiReq *A, rpcReq *C, bind func() error) error
|
|
after func(rpcResp *D, apiResp *B, bind func() error) error
|
|
}
|
|
|
|
func (a *RpcXXXX[A, B, C, D, Z]) Name(name string) *RpcXXXX[A, B, C, D, Z] {
|
|
a.name = name
|
|
return a
|
|
}
|
|
|
|
func (a *RpcXXXX[A, B, C, D, Z]) Before(fn func(apiReq *A, rpcReq *C, bind func() error) error) *RpcXXXX[A, B, C, D, Z] {
|
|
a.before = fn
|
|
return a
|
|
}
|
|
|
|
func (a *RpcXXXX[A, B, C, D, Z]) After(fn func(rpcResp *D, apiResp *B, bind func() error) error) *RpcXXXX[A, B, C, D, Z] {
|
|
a.after = fn
|
|
return a
|
|
}
|
|
|
|
func (a *RpcXXXX[A, B, C, D, Z]) defaultCopyReq(apiReq *A, rpcReq *C) error {
|
|
CopyAny(apiReq, rpcReq)
|
|
return nil
|
|
}
|
|
|
|
func (a *RpcXXXX[A, B, C, D, Z]) defaultCopyResp(rpcResp *D, apiResp *B) error {
|
|
CopyAny(rpcResp, apiResp)
|
|
return nil
|
|
}
|
|
|
|
func (a *RpcXXXX[A, B, C, D, Z]) getZtype() string {
|
|
return ""
|
|
}
|
|
|
|
func (a *RpcXXXX[A, B, C, D, Z]) GetGrpcConn() (*grpc.ClientConn, error) {
|
|
if a.name == "" {
|
|
a.name = nameMap[getName[Z]()]
|
|
}
|
|
// todo 获取连接
|
|
|
|
return nil, nil // todo
|
|
}
|
|
|
|
func (a *RpcXXXX[A, B, C, D, Z]) execute() (*B, error) {
|
|
var apiReq A
|
|
if err := a.bind.Bind(&apiReq); err != nil {
|
|
return nil, err
|
|
}
|
|
opID := a.bind.OperationID()
|
|
userID, err := a.bind.OpUserID()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
_, _ = opID, userID
|
|
var rpcReq C
|
|
if a.before == nil {
|
|
err = a.defaultCopyReq(&apiReq, &rpcReq)
|
|
} else {
|
|
err = a.before(&apiReq, &rpcReq, func() error { return a.defaultCopyReq(&apiReq, &rpcReq) })
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
conn, err := a.GetGrpcConn()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
rpcResp, err := a.rpc(a.client(conn), a.bind.Context(), &rpcReq)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var apiResp B
|
|
if a.after == nil {
|
|
err = a.defaultCopyResp(rpcResp, &apiResp)
|
|
} else {
|
|
err = a.after(rpcResp, &apiResp, func() error { return a.defaultCopyResp(rpcResp, &apiResp) })
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &apiResp, nil
|
|
}
|
|
|
|
func (a *RpcXXXX[A, B, C, D, Z]) Call() {
|
|
a.bind.Resp(a.execute())
|
|
}
|