improved interface{} support and refactored arg loading

This commit is contained in:
Jan Halfar 2017-07-25 08:46:42 +02:00
parent 3f9060cba6
commit d0164739e2
7 changed files with 142 additions and 52 deletions

View File

@ -122,6 +122,14 @@ type (
RetHello_1 *Err
}
DemoHelloInterfaceRequest struct {
Anything interface{}
AnythingMap map[string]interface{}
AnythingSlice []interface{}
}
DemoHelloInterfaceResponse struct {
}
DemoMapCrapRequest struct {
}
DemoMapCrapResponse struct {
@ -148,6 +156,8 @@ func init() {
gob.Register(DemoGiveMeAScalarResponse{})
gob.Register(DemoHelloRequest{})
gob.Register(DemoHelloResponse{})
gob.Register(DemoHelloInterfaceRequest{})
gob.Register(DemoHelloInterfaceResponse{})
gob.Register(DemoMapCrapRequest{})
gob.Register(DemoMapCrapResponse{})
gob.Register(DemoNestRequest{})
@ -205,6 +215,10 @@ func (p *DemoGoRPCProxy) handler(clientAddr string, request interface{}) (respon
req := request.(DemoHelloRequest)
retHello_0, retHello_1 := p.service.Hello(req.Name)
response = DemoHelloResponse{RetHello_0: retHello_0, RetHello_1: retHello_1}
case "DemoHelloInterfaceRequest":
req := request.(DemoHelloInterfaceRequest)
p.service.HelloInterface(req.Anything, req.AnythingMap, req.AnythingSlice)
response = DemoHelloInterfaceResponse{}
case "DemoMapCrapRequest":
crap := p.service.MapCrap()
response = DemoMapCrapResponse{Crap: crap}

View File

@ -21,17 +21,17 @@ func NewFooGoRPCClient(addr string, tlsConfig *tls.Config) *FooGoRPCClient {
return client
}
func (c *FooGoRPCClient) Start() {
c.Client.Start()
func (goTSRPCClientInstance *FooGoRPCClient) Start() {
goTSRPCClientInstance.Client.Start()
}
func (c *FooGoRPCClient) Stop() {
c.Client.Stop()
func (goTSRPCClientInstance *FooGoRPCClient) Stop() {
goTSRPCClientInstance.Client.Stop()
}
func (c *FooGoRPCClient) Hello(number int64) (retHello_0 int, clientErr error) {
func (goTSRPCClientInstance *FooGoRPCClient) Hello(number int64) (retHello_0 int, clientErr error) {
req := FooHelloRequest{Number: number}
rpcCallRes, rpcCallErr := c.Client.Call(req)
rpcCallRes, rpcCallErr := goTSRPCClientInstance.Client.Call(req)
if rpcCallErr != nil {
clientErr = rpcCallErr
return
@ -54,17 +54,17 @@ func NewDemoGoRPCClient(addr string, tlsConfig *tls.Config) *DemoGoRPCClient {
return client
}
func (c *DemoGoRPCClient) Start() {
c.Client.Start()
func (goTSRPCClientInstance *DemoGoRPCClient) Start() {
goTSRPCClientInstance.Client.Start()
}
func (c *DemoGoRPCClient) Stop() {
c.Client.Stop()
func (goTSRPCClientInstance *DemoGoRPCClient) Stop() {
goTSRPCClientInstance.Client.Stop()
}
func (c *DemoGoRPCClient) ExtractAddress(person *Person) (addr *Address, e *Err, clientErr error) {
func (goTSRPCClientInstance *DemoGoRPCClient) ExtractAddress(person *Person) (addr *Address, e *Err, clientErr error) {
req := DemoExtractAddressRequest{Person: person}
rpcCallRes, rpcCallErr := c.Client.Call(req)
rpcCallRes, rpcCallErr := goTSRPCClientInstance.Client.Call(req)
if rpcCallErr != nil {
clientErr = rpcCallErr
return
@ -73,9 +73,9 @@ func (c *DemoGoRPCClient) ExtractAddress(person *Person) (addr *Address, e *Err,
return response.Addr, response.E, nil
}
func (c *DemoGoRPCClient) GiveMeAScalar() (amount nested.Amount, wahr nested.True, hier ScalarInPlace, clientErr error) {
func (goTSRPCClientInstance *DemoGoRPCClient) GiveMeAScalar() (amount nested.Amount, wahr nested.True, hier ScalarInPlace, clientErr error) {
req := DemoGiveMeAScalarRequest{}
rpcCallRes, rpcCallErr := c.Client.Call(req)
rpcCallRes, rpcCallErr := goTSRPCClientInstance.Client.Call(req)
if rpcCallErr != nil {
clientErr = rpcCallErr
return
@ -84,9 +84,9 @@ func (c *DemoGoRPCClient) GiveMeAScalar() (amount nested.Amount, wahr nested.Tru
return response.Amount, response.Wahr, response.Hier, nil
}
func (c *DemoGoRPCClient) Hello(name string) (retHello_0 string, retHello_1 *Err, clientErr error) {
func (goTSRPCClientInstance *DemoGoRPCClient) Hello(name string) (retHello_0 string, retHello_1 *Err, clientErr error) {
req := DemoHelloRequest{Name: name}
rpcCallRes, rpcCallErr := c.Client.Call(req)
rpcCallRes, rpcCallErr := goTSRPCClientInstance.Client.Call(req)
if rpcCallErr != nil {
clientErr = rpcCallErr
return
@ -95,9 +95,19 @@ func (c *DemoGoRPCClient) Hello(name string) (retHello_0 string, retHello_1 *Err
return response.RetHello_0, response.RetHello_1, nil
}
func (c *DemoGoRPCClient) MapCrap() (crap map[string][]int, clientErr error) {
func (goTSRPCClientInstance *DemoGoRPCClient) HelloInterface(anything interface{}, anythingMap map[string]interface{}, anythingSlice []interface{}) (clientErr error) {
req := DemoHelloInterfaceRequest{Anything: anything, AnythingMap: anythingMap, AnythingSlice: anythingSlice}
_, rpcCallErr := goTSRPCClientInstance.Client.Call(req)
if rpcCallErr != nil {
clientErr = rpcCallErr
return
}
return nil
}
func (goTSRPCClientInstance *DemoGoRPCClient) MapCrap() (crap map[string][]int, clientErr error) {
req := DemoMapCrapRequest{}
rpcCallRes, rpcCallErr := c.Client.Call(req)
rpcCallRes, rpcCallErr := goTSRPCClientInstance.Client.Call(req)
if rpcCallErr != nil {
clientErr = rpcCallErr
return
@ -106,9 +116,9 @@ func (c *DemoGoRPCClient) MapCrap() (crap map[string][]int, clientErr error) {
return response.Crap, nil
}
func (c *DemoGoRPCClient) Nest() (retNest_0 *nested.Nested, clientErr error) {
func (goTSRPCClientInstance *DemoGoRPCClient) Nest() (retNest_0 *nested.Nested, clientErr error) {
req := DemoNestRequest{}
rpcCallRes, rpcCallErr := c.Client.Call(req)
rpcCallRes, rpcCallErr := goTSRPCClientInstance.Client.Call(req)
if rpcCallErr != nil {
clientErr = rpcCallErr
return
@ -117,9 +127,9 @@ func (c *DemoGoRPCClient) Nest() (retNest_0 *nested.Nested, clientErr error) {
return response.RetNest_0, nil
}
func (c *DemoGoRPCClient) TestScalarInPlace() (retTestScalarInPlace_0 ScalarInPlace, clientErr error) {
func (goTSRPCClientInstance *DemoGoRPCClient) TestScalarInPlace() (retTestScalarInPlace_0 ScalarInPlace, clientErr error) {
req := DemoTestScalarInPlaceRequest{}
rpcCallRes, rpcCallErr := c.Client.Call(req)
rpcCallRes, rpcCallErr := goTSRPCClientInstance.Client.Call(req)
if rpcCallErr != nil {
clientErr = rpcCallErr
return

View File

@ -55,7 +55,9 @@ func (p *FooGoTSRPCProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
switch funcName {
case "Hello":
arg_number := int64(0)
var (
arg_number int64
)
args = []interface{}{&arg_number}
err := gotsrpc.LoadArgs(&args, callStats, r)
if err != nil {
@ -122,7 +124,9 @@ func (p *DemoGoTSRPCProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
switch funcName {
case "ExtractAddress":
arg_person := &Person{}
var (
arg_person *Person
)
args = []interface{}{&arg_person}
err := gotsrpc.LoadArgs(&args, callStats, r)
if err != nil {
@ -145,7 +149,9 @@ func (p *DemoGoTSRPCProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
gotsrpc.Reply([]interface{}{giveMeAScalarAmount, giveMeAScalarWahr, giveMeAScalarHier}, callStats, r, w)
return
case "Hello":
arg_name := ""
var (
arg_name string
)
args = []interface{}{&arg_name}
err := gotsrpc.LoadArgs(&args, callStats, r)
if err != nil {
@ -159,6 +165,25 @@ func (p *DemoGoTSRPCProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
gotsrpc.Reply([]interface{}{helloRet, helloRet_1}, callStats, r, w)
return
case "HelloInterface":
var (
arg_anything interface{}
arg_anythingMap map[string]interface{}
arg_anythingSlice []interface{}
)
args = []interface{}{&arg_anything, &arg_anythingMap, &arg_anythingSlice}
err := gotsrpc.LoadArgs(&args, callStats, r)
if err != nil {
gotsrpc.ErrorCouldNotLoadArgs(w)
return
}
executionStart := time.Now()
p.service.HelloInterface(arg_anything, arg_anythingMap, arg_anythingSlice)
if callStats != nil {
callStats.Execution = time.Now().Sub(executionStart)
}
gotsrpc.Reply([]interface{}{}, callStats, r, w)
return
case "MapCrap":
executionStart := time.Now()
mapCrapCrap := p.service.MapCrap()

View File

@ -22,10 +22,10 @@ func NewFooGoTSRPCClient(url string, endpoint string) *FooGoTSRPCClient {
}
}
func (c *FooGoTSRPCClient) Hello(number int64) (retHello_0 int, clientErr error) {
func (goTSRPCClientInstance *FooGoTSRPCClient) Hello(number int64) (retHello_0 int, clientErr error) {
args := []interface{}{number}
reply := []interface{}{&retHello_0}
clientErr = gotsrpc.CallClient(c.URL, c.EndPoint, "Hello", args, reply)
clientErr = gotsrpc.CallClient(goTSRPCClientInstance.URL, goTSRPCClientInstance.EndPoint, "Hello", args, reply)
return
}
@ -45,44 +45,51 @@ func NewDemoGoTSRPCClient(url string, endpoint string) *DemoGoTSRPCClient {
}
}
func (c *DemoGoTSRPCClient) ExtractAddress(person *Person) (addr *Address, e *Err, clientErr error) {
func (goTSRPCClientInstance *DemoGoTSRPCClient) ExtractAddress(person *Person) (addr *Address, e *Err, clientErr error) {
args := []interface{}{person}
reply := []interface{}{&addr, &e}
clientErr = gotsrpc.CallClient(c.URL, c.EndPoint, "ExtractAddress", args, reply)
clientErr = gotsrpc.CallClient(goTSRPCClientInstance.URL, goTSRPCClientInstance.EndPoint, "ExtractAddress", args, reply)
return
}
func (c *DemoGoTSRPCClient) GiveMeAScalar() (amount nested.Amount, wahr nested.True, hier ScalarInPlace, clientErr error) {
func (goTSRPCClientInstance *DemoGoTSRPCClient) GiveMeAScalar() (amount nested.Amount, wahr nested.True, hier ScalarInPlace, clientErr error) {
args := []interface{}{}
reply := []interface{}{&amount, &wahr, &hier}
clientErr = gotsrpc.CallClient(c.URL, c.EndPoint, "GiveMeAScalar", args, reply)
clientErr = gotsrpc.CallClient(goTSRPCClientInstance.URL, goTSRPCClientInstance.EndPoint, "GiveMeAScalar", args, reply)
return
}
func (c *DemoGoTSRPCClient) Hello(name string) (retHello_0 string, retHello_1 *Err, clientErr error) {
func (goTSRPCClientInstance *DemoGoTSRPCClient) Hello(name string) (retHello_0 string, retHello_1 *Err, clientErr error) {
args := []interface{}{name}
reply := []interface{}{&retHello_0, &retHello_1}
clientErr = gotsrpc.CallClient(c.URL, c.EndPoint, "Hello", args, reply)
clientErr = gotsrpc.CallClient(goTSRPCClientInstance.URL, goTSRPCClientInstance.EndPoint, "Hello", args, reply)
return
}
func (c *DemoGoTSRPCClient) MapCrap() (crap map[string][]int, clientErr error) {
func (goTSRPCClientInstance *DemoGoTSRPCClient) HelloInterface(anything interface{}, anythingMap map[string]interface{}, anythingSlice []interface{}) (clientErr error) {
args := []interface{}{anything, anythingMap, anythingSlice}
reply := []interface{}{}
clientErr = gotsrpc.CallClient(goTSRPCClientInstance.URL, goTSRPCClientInstance.EndPoint, "HelloInterface", args, reply)
return
}
func (goTSRPCClientInstance *DemoGoTSRPCClient) MapCrap() (crap map[string][]int, clientErr error) {
args := []interface{}{}
reply := []interface{}{&crap}
clientErr = gotsrpc.CallClient(c.URL, c.EndPoint, "MapCrap", args, reply)
clientErr = gotsrpc.CallClient(goTSRPCClientInstance.URL, goTSRPCClientInstance.EndPoint, "MapCrap", args, reply)
return
}
func (c *DemoGoTSRPCClient) Nest() (retNest_0 *nested.Nested, clientErr error) {
func (goTSRPCClientInstance *DemoGoTSRPCClient) Nest() (retNest_0 *nested.Nested, clientErr error) {
args := []interface{}{}
reply := []interface{}{&retNest_0}
clientErr = gotsrpc.CallClient(c.URL, c.EndPoint, "Nest", args, reply)
clientErr = gotsrpc.CallClient(goTSRPCClientInstance.URL, goTSRPCClientInstance.EndPoint, "Nest", args, reply)
return
}
func (c *DemoGoTSRPCClient) TestScalarInPlace() (retTestScalarInPlace_0 ScalarInPlace, clientErr error) {
func (goTSRPCClientInstance *DemoGoTSRPCClient) TestScalarInPlace() (retTestScalarInPlace_0 ScalarInPlace, clientErr error) {
args := []interface{}{}
reply := []interface{}{&retTestScalarInPlace_0}
clientErr = gotsrpc.CallClient(c.URL, c.EndPoint, "TestScalarInPlace", args, reply)
clientErr = gotsrpc.CallClient(goTSRPCClientInstance.URL, goTSRPCClientInstance.EndPoint, "TestScalarInPlace", args, reply)
return
}

32
go.go
View File

@ -25,7 +25,7 @@ func (v *Value) goType(aliases map[string]string, packageName string) (t string)
case len(v.GoScalarType) > 0:
t += v.GoScalarType
case v.StructType != nil:
if packageName != v.StructType.Package {
if packageName != v.StructType.Package && aliases[v.StructType.Package] != "" {
t += aliases[v.StructType.Package] + "."
}
t += v.StructType.Name
@ -37,6 +37,8 @@ func (v *Value) goType(aliases map[string]string, packageName string) (t string)
t += aliases[v.Scalar.Package] + "."
}
t += v.Scalar.Name[len(v.Scalar.Package)+1:]
case v.IsInterface:
t += "interface{}"
default:
// TODO
fmt.Println("WARN: can't resolve goType")
@ -51,6 +53,8 @@ func (v *Value) emptyLiteral(aliases map[string]string) (e string) {
e += "&"
}
switch true {
case v.Map != nil:
e += "map[" + v.Map.KeyType + "]" + v.Map.Value.emptyLiteral(aliases)
case len(v.GoScalarType) > 0:
switch v.GoScalarType {
case "string":
@ -105,7 +109,8 @@ func (v *Value) emptyLiteral(aliases map[string]string) (e string) {
e += alias + "."
}
e += v.StructType.Name + "{}"
case v.IsInterface:
e += "interface{}{}"
}
return
}
@ -290,14 +295,17 @@ func renderTSRPCServiceProxies(services ServiceList, fullPackageName string, pac
continue
}
argsDecls = append(argsDecls, argName+" := "+arg.Value.emptyLiteral(aliases))
//argsDecls = append(argsDecls, argName+" := "+arg.Value.emptyLiteral(aliases))
argsDecls = append(argsDecls, argName+" "+arg.Value.goType(aliases, packageName))
args = append(args, "&"+argName)
callArgs = append(callArgs, argName)
skipArgI++
}
g.l("var (")
for _, argDecl := range argsDecls {
g.l(argDecl)
}
g.l(")")
g.l("args = []interface{}{" + strings.Join(args, ", ") + "}")
g.l("err := gotsrpc.LoadArgs(&args, callStats, r)")
g.l("if err != nil {")
@ -416,10 +424,10 @@ func renderTSRPCServiceClients(services ServiceList, fullPackageName string, pac
returns = append(returns, name+" "+r.Value.goType(aliases, fullPackageName))
}
returns = append(returns, "clientErr error")
g.l(`func (c *` + clientName + `) ` + method.Name + `(` + strings.Join(params, ", ") + `) (` + strings.Join(returns, ", ") + `) {`)
g.l(`func (goTSRPCClientInstance *` + clientName + `) ` + method.Name + `(` + strings.Join(params, ", ") + `) (` + strings.Join(returns, ", ") + `) {`)
g.l(`args := []interface{}{` + strings.Join(args, ", ") + `}`)
g.l(`reply := []interface{}{` + strings.Join(rets, ", ") + `}`)
g.l(`clientErr = gotsrpc.CallClient(c.URL, c.EndPoint, "` + method.Name + `", args, reply)`)
g.l(`clientErr = gotsrpc.CallClient(goTSRPCClientInstance.URL, goTSRPCClientInstance.EndPoint, "` + method.Name + `", args, reply)`)
g.l(`return`)
g.l(`}`)
g.nl()
@ -647,12 +655,12 @@ func renderGoRPCServiceClients(services ServiceList, fullPackageName string, pac
return client
}
func (c *` + clientName + `) Start() {
c.Client.Start()
func (goTSRPCClientInstance *` + clientName + `) Start() {
goTSRPCClientInstance.Client.Start()
}
func (c *` + clientName + `) Stop() {
c.Client.Stop()
func (goTSRPCClientInstance *` + clientName + `) Stop() {
goTSRPCClientInstance.Client.Stop()
}
`)
g.nl()
@ -675,12 +683,12 @@ func renderGoRPCServiceClients(services ServiceList, fullPackageName string, pac
returns = append(returns, name+" "+r.Value.goType(aliases, fullPackageName))
}
returns = append(returns, "clientErr error")
g.l(`func (c *` + clientName + `) ` + method.Name + `(` + strings.Join(params, ", ") + `) (` + strings.Join(returns, ", ") + `) {`)
g.l(`func (goTSRPCClientInstance *` + clientName + `) ` + method.Name + `(` + strings.Join(params, ", ") + `) (` + strings.Join(returns, ", ") + `) {`)
g.l(`req := ` + service.Name + method.Name + `Request{` + strings.Join(args, ", ") + `}`)
if len(rets) > 0 {
g.l(`rpcCallRes, rpcCallErr := c.Client.Call(req)`)
g.l(`rpcCallRes, rpcCallErr := goTSRPCClientInstance.Client.Call(req)`)
} else {
g.l(`_, rpcCallErr := c.Client.Call(req)`)
g.l(`_, rpcCallErr := goTSRPCClientInstance.Client.Call(req)`)
}
g.l(`if rpcCallErr != nil {`)
g.l(`clientErr = rpcCallErr`)

View File

@ -23,3 +23,29 @@ func TestLoadArgs(t *testing.T) {
t.Fatal("bar[1] (", bar[1], ") != b")
}
}
func TestLoadInterfaceArgs(t *testing.T) {
jsonBytes := []byte(`["a", ["a", "b", "c"], 1.3]`)
var (
foo interface{}
bar []interface{}
floaty interface{}
)
args := []interface{}{&foo, &bar, &floaty}
errLoad := loadArgs(&args, jsonBytes)
if errLoad != nil {
t.Fatal(errLoad)
}
if foo != "a" {
t.Fatal("foo should have been a")
}
if len(bar) != 3 {
t.Fatal("bar len wrong", len(bar), "!=", len(bar))
}
if bar[1] != "b" {
t.Fatal("bar[1] (", bar[1], ") != b")
}
if floaty != 1.3 {
t.Fatal("floaty mismatch", floaty)
}
}

View File

@ -8,7 +8,7 @@ import (
)
func getTestServiceList(t *testing.T) ServiceList {
ReaderTrace = true
// ReaderTrace = true
serviceMap := map[string]string{
"/demo": "Demo",
}