rpc: Add CallContractSingle method to pass non-array argument

This commit is contained in:
Nicolas Gotchac 2023-01-03 15:35:56 +01:00
parent 16946d218a
commit 728265316f
2 changed files with 32 additions and 5 deletions

View file

@ -335,10 +335,22 @@ func (c *Client) Call(result interface{}, method string, args ...interface{}) er
// The result must be a pointer so that package json can unmarshal into it. You
// can also pass nil, in which case the result is ignored.
func (c *Client) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error {
return c.CallContextSingle(ctx, result, method, args)
}
// CallContextSingle performs a JSON-RPC call with the given single argument
// (which should serialize to an array or an object). If the context is canceled before
// the call has successfully returned, CallContextSingle returns immediately.
//
// The result must be a pointer so that package json can unmarshal into it. You
// can also pass nil, in which case the result is ignored.
//
// If the given args is a list, it behaves as CallContext
func (c *Client) CallContextSingle(ctx context.Context, result interface{}, method string, arg interface{}) error {
if result != nil && reflect.TypeOf(result).Kind() != reflect.Ptr {
return fmt.Errorf("call result parameter must be pointer or nil interface: %v", result)
}
msg, err := c.newMessage(method, args...)
msg, err := c.newMessage(method, arg)
if err != nil {
return err
}
@ -406,7 +418,7 @@ func (c *Client) BatchCallContext(ctx context.Context, b []BatchElem) error {
resp: make(chan []*jsonrpcMessage, 1),
}
for i, elem := range b {
msg, err := c.newMessage(elem.Method, elem.Args...)
msg, err := c.newMessage(elem.Method, elem.Args)
if err != nil {
return err
}
@ -469,7 +481,7 @@ func (c *Client) BatchCallContext(ctx context.Context, b []BatchElem) error {
// Notify sends a notification, i.e. a method call that doesn't expect a response.
func (c *Client) Notify(ctx context.Context, method string, args ...interface{}) error {
op := new(requestOp)
msg, err := c.newMessage(method, args...)
msg, err := c.newMessage(method, args)
if err != nil {
return err
}
@ -517,7 +529,7 @@ func (c *Client) Subscribe(ctx context.Context, namespace string, channel interf
return nil, ErrNotificationsUnsupported
}
msg, err := c.newMessage(namespace+subscribeMethodSuffix, args...)
msg, err := c.newMessage(namespace+subscribeMethodSuffix, args)
if err != nil {
return nil, err
}
@ -545,7 +557,7 @@ func (c *Client) SupportsSubscriptions() bool {
return !c.isHTTP
}
func (c *Client) newMessage(method string, paramsIn ...interface{}) (*jsonrpcMessage, error) {
func (c *Client) newMessage(method string, paramsIn interface{}) (*jsonrpcMessage, error) {
msg := &jsonrpcMessage{Version: vsn, ID: c.nextID(), Method: method}
if paramsIn != nil { // prevent sending "params":null
var err error

View file

@ -52,6 +52,21 @@ func TestClientRequest(t *testing.T) {
}
}
func TestClientRequestSingle(t *testing.T) {
server := newTestServer()
defer server.Stop()
client := DialInProc(server)
defer client.Close()
var resp echoResult
if err := client.CallContextSingle(context.Background(), &resp, "test_echo", []interface{}{"hello", 10, &echoArgs{"world"}}); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(resp, echoResult{"hello", 10, &echoArgs{"world"}}) {
t.Errorf("incorrect result %#v", resp)
}
}
func TestClientResponseType(t *testing.T) {
server := newTestServer()
defer server.Stop()