From 32aea5406aa5c2dba6b783cec0e22bf0bb5d4685 Mon Sep 17 00:00:00 2001
From: a <a@a.a>
Date: Fri, 2 Sep 2022 20:49:31 -0500
Subject: [PATCH] add callp

---
 client.go | 80 ++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 58 insertions(+), 22 deletions(-)

diff --git a/client.go b/client.go
index 5102e9d..9e77cfa 100644
--- a/client.go
+++ b/client.go
@@ -262,6 +262,53 @@ func (c *Client) SetHeader(key, value string) {
 	conn.mu.Unlock()
 }
 
+func (c *Client) call(ctx context.Context, result any, msg *jsonrpcMessage) error {
+	var err error
+	op := &requestOp{ids: []json.RawMessage{msg.ID.RawMessage()}, resp: make(chan *jsonrpcMessage, 1)}
+
+	if c.isHTTP {
+		err = c.sendHTTP(ctx, op, msg)
+	} else {
+		err = c.send(ctx, op, msg)
+	}
+	if err != nil {
+		return err
+	}
+	// dispatch has accepted the request and will close the channel when it quits.
+	resp, err := op.wait(ctx, c)
+	if err != nil {
+		return err
+	}
+	switch {
+	case resp.Error != nil:
+		return resp.Error
+	case len(resp.Result) == 0:
+		return ErrNoResult
+	default:
+		return json.Unmarshal(resp.Result, &result)
+	}
+}
+
+func (c *Client) CallP(result any, method string, param any) error {
+	ctx := context.Background()
+	return c.CallPContext(ctx, result, method, param)
+}
+
+// CallPContext is call except it uh uses a param instead of the variadic args
+// TODO: we should probably rewrite Call and CallContext to just call CallP and CallPContext
+//
+//	i havent done this because i want to make sure that callp and callpcontext work
+func (c *Client) CallPContext(ctx context.Context, result any, method string, param any) 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.newMessageP(method, param)
+	if err != nil {
+		return err
+	}
+	return c.call(ctx, result, msg)
+}
+
 // Call performs a JSON-RPC call with the given arguments and unmarshals into
 // result if no error occurred.
 //
@@ -285,29 +332,8 @@ func (c *Client) CallContext(ctx context.Context, result any, method string, arg
 	if err != nil {
 		return err
 	}
-	op := &requestOp{ids: []json.RawMessage{msg.ID.RawMessage()}, resp: make(chan *jsonrpcMessage, 1)}
 
-	if c.isHTTP {
-		err = c.sendHTTP(ctx, op, msg)
-	} else {
-		err = c.send(ctx, op, msg)
-	}
-	if err != nil {
-		return err
-	}
-	// dispatch has accepted the request and will close the channel when it quits.
-	resp, err := op.wait(ctx, c)
-	if err != nil {
-		return err
-	}
-	switch {
-	case resp.Error != nil:
-		return resp.Error
-	case len(resp.Result) == 0:
-		return ErrNoResult
-	default:
-		return json.Unmarshal(resp.Result, &result)
-	}
+	return c.call(ctx, result, msg)
 }
 
 // BatchCall sends all given requests as a single batch and waits for the server
@@ -407,6 +433,16 @@ func (c *Client) newMessage(method string, paramsIn ...any) (*jsonrpcMessage, er
 	}
 	return msg, nil
 }
+func (c *Client) newMessageP(method string, paramIn any) (*jsonrpcMessage, error) {
+	msg := &jsonrpcMessage{ID: c.nextID(), Method: method}
+	if paramIn != nil { // prevent sending "params":null
+		var err error
+		if msg.Params, err = json.Marshal(paramIn); err != nil {
+			return nil, err
+		}
+	}
+	return msg, nil
+}
 
 // send registers op with the dispatch loop, then sends msg on the connection.
 // if sending fails, op is deregistered.
-- 
GitLab