Skip to content

Commit

Permalink
add StructType & ListType support for default codec
Browse files Browse the repository at this point in the history
  • Loading branch information
andot committed Feb 18, 2024
1 parent acee437 commit 7f440d6
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 4 deletions.
6 changes: 5 additions & 1 deletion rpc/core/client_codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
| |
| rpc/core/client_codec.go |
| |
| LastModified: Feb 27, 2022 |
| LastModified: Feb 18, 2024 |
| Author: Ma Bingyao <[email protected]> |
| |
\*________________________________________________________*/
Expand All @@ -29,6 +29,8 @@ type clientCodec struct {
io.LongType
io.RealType
io.MapType
io.StructType
io.ListType
}

// Encode request.
Expand Down Expand Up @@ -60,6 +62,8 @@ func (c clientCodec) Decode(response []byte, context *ClientContext) (result []i
decoder.LongType = c.LongType
decoder.RealType = c.RealType
decoder.MapType = c.MapType
decoder.StructType = c.StructType
decoder.ListType = c.ListType
tag := decoder.NextByte()
if tag == io.TagHeader {
var h map[string]interface{}
Expand Down
26 changes: 25 additions & 1 deletion rpc/core/codec_option.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
| |
| rpc/core/codec_option.go |
| |
| LastModified: Jun 16, 2021 |
| LastModified: Feb 18, 2024 |
| Author: Ma Bingyao <[email protected]> |
| |
\*________________________________________________________*/
Expand Down Expand Up @@ -74,3 +74,27 @@ func WithMapType(mapType io.MapType) CodecOption {
}
}
}

// WithStructType returns a structType Option for clientCodec & serviceCodec.
func WithStructType(structType io.StructType) CodecOption {
return func(c interface{}) {
switch c := c.(type) {
case *serviceCodec:
c.StructType = structType
case *clientCodec:
c.StructType = structType
}
}
}

// WithListType returns a listType Option for clientCodec & serviceCodec.
func WithListType(listType io.ListType) CodecOption {
return func(c interface{}) {
switch c := c.(type) {
case *serviceCodec:
c.ListType = listType
case *clientCodec:
c.ListType = listType
}
}
}
6 changes: 5 additions & 1 deletion rpc/core/service_codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
| |
| rpc/core/service_codec.go |
| |
| LastModified: Feb 27, 2022 |
| LastModified: Feb 18, 2024 |
| Author: Ma Bingyao <[email protected]> |
| |
\*________________________________________________________*/
Expand All @@ -32,6 +32,8 @@ type serviceCodec struct {
io.LongType
io.RealType
io.MapType
io.StructType
io.ListType
}

// Encode response.
Expand Down Expand Up @@ -75,6 +77,8 @@ func (c serviceCodec) Decode(request []byte, context *ServiceContext) (name stri
decoder.LongType = c.LongType
decoder.RealType = c.RealType
decoder.MapType = c.MapType
decoder.StructType = c.StructType
decoder.ListType = c.ListType
tag := decoder.NextByte()
if tag == io.TagHeader {
var h map[string]interface{}
Expand Down
39 changes: 38 additions & 1 deletion rpc/mock/mock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
| |
| rpc/mock/mock_test.go |
| |
| LastModified: May 7, 2021 |
| LastModified: Feb 18, 2024 |
| Author: Ma Bingyao <[email protected]> |
| |
\*________________________________________________________*/
Expand All @@ -24,6 +24,7 @@ import (
"testing"
"time"

"github.com/hprose/hprose-golang/v3/io"
"github.com/hprose/hprose-golang/v3/rpc/core"
. "github.com/hprose/hprose-golang/v3/rpc/mock"
"github.com/hprose/hprose-golang/v3/rpc/plugins/circuitbreaker"
Expand Down Expand Up @@ -59,6 +60,9 @@ func TestHelloWorld(t *testing.T) {
result, err := proxy.Hello("world")
assert.Equal(t, "hello world", result)
assert.NoError(t, err)
results, err := client.Invoke("hello", []interface{}{"world"})
assert.Equal(t, "hello world", results[0])
assert.NoError(t, err)
server.Close()
}

Expand Down Expand Up @@ -1323,3 +1327,36 @@ func TestClientAbort(t *testing.T) {
assert.Greater(t, n, int32(0))
server.Close()
}

func TestReturnStructSlice(t *testing.T) {
type User struct {
Name string
Age int
}
io.RegisterName("User", (*User)(nil))
service := core.NewService()
service.AddFunction(func() []User {
return []User{{"Tom", 18}, {"Jerry", 20}}
}, "users")
server := Server{Address: "testReturnStructSlice"}
err := service.Bind(server)
assert.NoError(t, err)
client := core.NewClient("mock://testReturnStructSlice")
client.Codec = core.NewClientCodec(
core.WithStructType(io.StructTypeStructObject),
core.WithListType(io.ListTypeSlice),
)
var proxy struct {
Users func() ([]User, error)
}
client.UseService(&proxy)
result, err := proxy.Users()
if assert.NoError(t, err) {
assert.Equal(t, []User{{"Tom", 18}, {"Jerry", 20}}, result)
}
results, err := client.Invoke("users", nil)
if assert.NoError(t, err) {
assert.Equal(t, []User{{"Tom", 18}, {"Jerry", 20}}, results[0])
}
server.Close()
}

0 comments on commit 7f440d6

Please sign in to comment.