2024-06-22 15:37:15 +00:00
|
|
|
package jsonrpc2
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"encoding/json"
|
2024-11-18 21:25:49 +00:00
|
|
|
"errors"
|
2024-06-22 15:37:15 +00:00
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
)
|
|
|
|
|
|
|
|
type rwClient struct {
|
|
|
|
enc *json.Encoder
|
|
|
|
dec *json.Decoder
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewReadWriterClient returns a Client which will use the given ReadWriter to
|
|
|
|
// perform requests.
|
|
|
|
func NewReadWriterClient(rw io.ReadWriter) Client {
|
|
|
|
return rwClient{json.NewEncoder(rw), json.NewDecoder(rw)}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c rwClient) Call(
|
2024-09-23 17:04:14 +00:00
|
|
|
ctx context.Context, rcv any, method string, args ...any,
|
2024-06-22 15:37:15 +00:00
|
|
|
) error {
|
2024-09-23 17:04:14 +00:00
|
|
|
id, err := encodeRequest(ctx, c.enc, method, args)
|
2024-06-22 15:37:15 +00:00
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("encoding request: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
resID, err := decodeResponse(c.dec, rcv)
|
2024-11-18 21:25:49 +00:00
|
|
|
if errors.As(err, new(Error)) {
|
|
|
|
return err
|
|
|
|
} else if err != nil {
|
2024-06-22 15:37:15 +00:00
|
|
|
return fmt.Errorf("decoding response: %w", err)
|
|
|
|
} else if resID != id {
|
|
|
|
return fmt.Errorf(
|
|
|
|
"expected response with ID %q, got %q", id, resID,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|