diff --git a/base.go b/base.go index 7d0091b..ed07bdd 100644 --- a/base.go +++ b/base.go @@ -10,7 +10,7 @@ import ( "strings" ) -// An Assigner maps method names to Handler functions. +// An Assigner maps method names to [Handler] functions. type Assigner interface { // Assign returns the handler for the named method, or returns nil to // indicate that the method is not known. @@ -20,8 +20,8 @@ type Assigner interface { Assign(ctx context.Context, method string) Handler } -// Namer is an optional interface that an Assigner may implement to expose the -// names of its methods to the ServerInfo method. +// Namer is an optional interface that an [Assigner] may implement to expose +// the names of its methods to the ServerInfo method. type Namer interface { // Names returns all known method names in lexicographic order. Names() []string @@ -33,8 +33,8 @@ type Namer interface { // of type *jrpc2.Error to control the response code sent back to the caller; // otherwise the server will wrap the resulting value. // -// The context passed to the handler by a *jrpc2.Server includes two special -// values that the handler may extract. +// The context passed to the handler by a [Server] includes two special values +// that the handler may extract. // // To obtain the server instance running the handler, write: // @@ -75,10 +75,10 @@ func (r *Request) HasParams() bool { return len(r.params) != 0 } // By default, unknown object keys are ignored and discarded when unmarshaling // into a v of struct type. If the type of v implements a DisallowUnknownFields // method, unknown fields will instead generate an InvalidParams error. The -// jrpc2.StrictFields helper adapts existing struct values to this interface. -// For more specific behaviour, implement a custom json.Unmarshaler. +// [StrictFields] helper adapts existing struct values to this interface. For +// more specific behaviour, implement a custom [json.Unmarshaler]. // -// If v has type *json.RawMessage, unmarshaling will never report an error. +// If v has type [*json.RawMessage], unmarshaling will never report an error. func (r *Request) UnmarshalParams(v any) error { if len(r.params) == 0 { return nil @@ -134,11 +134,11 @@ func (r *Response) Error() *Error { return r.err } // // By default, unknown object keys are ignored and discarded when unmarshaling // into a v of struct type. If the type of v implements a DisallowUnknownFields -// method, unknown fields will instead generate an error. The -// jrpc2.StrictFields helper adapts existing struct values to this interface. -// For more specific behaviour, implement a custom json.Unmarshaler. +// method, unknown fields will instead generate an error. The [StrictFields] +// helper adapts existing struct values to this interface. For more specific +// behaviour, implement a custom [json.Unmarshaler]. // -// If v has type *json.RawMessage, unmarshaling will never report an error. +// If v has type [*json.RawMessage], unmarshaling will never report an error. func (r *Response) UnmarshalResult(v any) error { if r.err != nil { return r.err diff --git a/channel/channel.go b/channel/channel.go index 18668c2..620b49c 100644 --- a/channel/channel.go +++ b/channel/channel.go @@ -2,9 +2,9 @@ // Package channel defines a communications channel. // -// A Channel encodes/transmits and decodes/receives data records. The types in -// this package support sending and receiving over an unstructured stream using -// a configurable framing discipline. +// A [Channel] encodes/transmits and decodes/receives data records. The types +// in this package support sending and receiving over an unstructured stream +// using a configurable framing discipline. // // # Channels // @@ -23,7 +23,7 @@ // // # Framing // -// A Framing function adapts a pair of io.Reader and io.WriteCloser to a +// A [Framing] function adapts a pair of [io.Reader] and [io.WriteCloser] to a // Channel by imposing a particular message-framing discipline. This package // provides several framing implementations, for example: // diff --git a/channel/hdr.go b/channel/hdr.go index 660fa30..e9c74a9 100644 --- a/channel/hdr.go +++ b/channel/hdr.go @@ -12,8 +12,8 @@ import ( "strings" ) -// StrictHeader defines a Framing that transmits and receives messages using a -// header prefix similar to HTTP, in which mimeType describes the content type. +// StrictHeader defines a [Framing] that transmits and receives messages using +// a header prefix similar to HTTP, in which mimeType describes the content type. // // Specifically, each message is sent in the format: // @@ -54,7 +54,7 @@ func StrictHeader(mimeType string) Framing { } } -// A ContentTypeMismatchError is reported by the Recv method of a Header +// A ContentTypeMismatchError is reported by the Recv method of a [Header] // framing when the content type of the message does not match the type // expected by the channel. type ContentTypeMismatchError struct { @@ -90,10 +90,11 @@ func (h *hdr) Send(msg []byte) error { return err } -// Recv implements part of the Channel interface. If the content type of the +// Recv implements part of the [Channel] interface. If the content type of the // received message does not match the expected value, Recv returns the decoded -// message along with an error of concrete type *ContentTypeMismatchError. The -// caller may choose to ignore this error by testing explicitly for this type. +// message along with an error of concrete type [*ContentTypeMismatchError]. +// The caller may choose to ignore this error by testing explicitly for this +// type. func (h *hdr) Recv() ([]byte, error) { var contentType, contentLength string for { @@ -149,10 +150,10 @@ func (h *hdr) Recv() ([]byte, error) { return data[:size], contentErr } -// Close implements part of the Channel interface. +// Close implements part of the [Channel] interface. func (h *hdr) Close() error { return h.wc.Close() } -// Header returns a framing that behaves as StrictHeader, but allows received +// Header returns a framing that behaves as [StrictHeader], but allows received // messages to omit the Content-Type header without error. An error will still // be reported if a content-type is set but does not match. func Header(mimeType string) Framing { @@ -174,8 +175,8 @@ func (o opthdr) Recv() ([]byte, error) { return msg, err } -// LSP is a header framing (see Header) that transmits and receives messages on -// r and wc using the MIME type application/vscode-jsonrpc. This is the format -// preferred by the Language Server Protocol (LSP), defined by +// LSP is a header framing (see [Header]) that transmits and receives messages +// on r and wc using the MIME type application/vscode-jsonrpc. This is the +// format preferred by the Language Server Protocol (LSP), defined by // https://microsoft.github.io/language-server-protocol var LSP = Header("application/vscode-jsonrpc; charset=utf-8") diff --git a/channel/json.go b/channel/json.go index 9257088..3630cf3 100644 --- a/channel/json.go +++ b/channel/json.go @@ -28,7 +28,7 @@ type jsonc struct { buf json.RawMessage } -// Send implements part of the Channel interface. +// Send implements part of the [Channel] interface. func (c jsonc) Send(msg []byte) error { if len(msg) == 0 || isNull(msg) { _, err := io.WriteString(c.wc, "null\n") @@ -38,9 +38,9 @@ func (c jsonc) Send(msg []byte) error { return err } -// Recv implements part of the Channel interface. It reports an error if the +// Recv implements part of the [Channel] interface. It reports an error if the // message is not a structurally valid JSON value. It is safe for the caller to -// treat any record returned as a json.RawMessage. +// treat any record returned as a [json.RawMessage]. func (c jsonc) Recv() ([]byte, error) { c.buf = c.buf[:0] // reset if err := c.dec.Decode(&c.buf); err != nil { @@ -51,7 +51,7 @@ func (c jsonc) Recv() ([]byte, error) { return c.buf, nil } -// Close implements part of the Channel interface. +// Close implements part of the [Channel] interface. func (c jsonc) Close() error { return c.wc.Close() } func isNull(msg json.RawMessage) bool { diff --git a/channel/split.go b/channel/split.go index 6f4a874..b63b3ee 100644 --- a/channel/split.go +++ b/channel/split.go @@ -30,7 +30,7 @@ type split struct { buf *bufio.Reader } -// Send implements part of the Channel interface. It reports an error if msg +// Send implements part of the [Channel] interface. It reports an error if msg // contains a split byte. func (c split) Send(msg []byte) error { if bytes.IndexByte(msg, c.split) >= 0 { @@ -41,7 +41,7 @@ func (c split) Send(msg []byte) error { return err } -// Recv implements part of the Channel interface. +// Recv implements part of the [Channel] interface. func (c split) Recv() ([]byte, error) { var buf bytes.Buffer for { @@ -58,5 +58,5 @@ func (c split) Recv() ([]byte, error) { } } -// Close implements part of the Channel interface. +// Close implements part of the [Channel] interface. func (c split) Close() error { return c.wc.Close() } diff --git a/client.go b/client.go index c3cbc20..b13ff72 100644 --- a/client.go +++ b/client.go @@ -14,7 +14,7 @@ import ( ) // A Client is a JSON-RPC 2.0 client. The client sends requests and receives -// responses on a channel.Channel provided by the constructor. +// responses on a [channel.Channel] provided by the constructor. type Client struct { done *sync.WaitGroup // done when the reader is finished at shutdown time @@ -289,7 +289,7 @@ func (c *Client) waitComplete(pctx context.Context, id string, p *Response) { // Call initiates a single request and blocks until the response returns or ctx // ends. A successful call reports a nil error and a non-nil response. Errors -// from the server have concrete type *jrpc2.Error. +// from the server have concrete type [*Error]. // // rsp, err := c.Call(ctx, method, params) // if e, ok := err.(*jrpc2.Error); ok { diff --git a/code.go b/code.go index dd3aa71..c31c33f 100644 --- a/code.go +++ b/code.go @@ -48,9 +48,9 @@ func (c codeError) Is(err error) bool { return ok && v.ErrCode() == Code(c) } -// Err converts c to an error value, which is nil for NoError and otherwise an -// error value whose code is c and whose text is based on the built-in string -// for c if one exists. +// Err converts c to an error value, which is nil for [NoError] and otherwise +// an error value whose code is c and whose text is based on the built-in +// string for c if one exists. func (c Code) Err() error { if c == NoError { return nil diff --git a/ctx.go b/ctx.go index bac2b35..9146c44 100644 --- a/ctx.go +++ b/ctx.go @@ -8,7 +8,7 @@ import ( // InboundRequest returns the inbound request associated with the context // passed to a Handler, or nil if ctx does not have an inbound request. -// A *jrpc2.Server populates this value for handler contexts. +// A [Server] populates this value for handler contexts. // // This is mainly useful to wrapped server methods that do not have the request // as an explicit parameter; for direct implementations of the Handler type the @@ -24,19 +24,19 @@ func InboundRequest(ctx context.Context) *Request { type inboundRequestKey struct{} // ServerFromContext returns the server associated with the context passed to a -// Handler by a *jrpc2.Server. It will panic for a non-handler context. +// [Handler] by a [Server]. It will panic for a non-handler context. // // It is safe to retain the server and invoke its methods beyond the lifetime // of the context from which it was extracted; however, a handler must not -// block on the Wait or WaitStatus methods of the server, as the server will -// deadlock waiting for the handler to return. +// block on the [Server.Wait] or [Server.WaitStatus] methods, as the server +// will deadlock waiting for the handler to return. func ServerFromContext(ctx context.Context) *Server { return ctx.Value(serverKey{}).(*Server) } type serverKey struct{} // ClientFromContext returns the client associated with the given context. -// This will be populated on the context passed by a *jrpc2.Client to a -// client-side callback handler. +// This will be populated on the context passed by a [Client] to a client-side +// callback handler. // // A callback handler MUST NOT close the client, as the close will deadlock // waiting for the callback to return. diff --git a/doc.go b/doc.go index f7181eb..fd5e124 100644 --- a/doc.go +++ b/doc.go @@ -6,15 +6,15 @@ defined by http://www.jsonrpc.org/specification. # Servers -The *Server type implements a JSON-RPC server. A server communicates with a -client over a channel.Channel, and dispatches client requests to user-defined +The [*Server] type implements a JSON-RPC server. A server communicates with a +client over a [channel.Channel], and dispatches client requests to user-defined method handlers. Method handlers are functions with this signature: func(ctx Context.Context, req *jrpc2.Request) (any, error) -A server finds the handler for a request by looking up its method name in a -jrpc2.Assigner. A Handler decodes request parameters using the UnmarshalParams -method on the Request: +A server finds the handler for a request by looking up its method name in an +[Assigner]. A [Handler] decodes request parameters using the UnmarshalParams +method on the [Request]: func Handle(ctx context.Context, req *jrpc2.Request) (any, error) { var args ArgType @@ -24,8 +24,8 @@ method on the Request: return usefulStuffWith(args) } -The handler package uses reflection to adapt functions that do not have this -type to handlers. For example, given: +The [github.com/creachadair/jrpc2/handler] package uses reflection to adapt +functions that do not have this type to handlers. For example, given: // Add returns the sum of a slice of integers. func Add(ctx context.Context, values []int) int { @@ -47,14 +47,14 @@ interface with a Go map. To advertise this function under the name "Add": "Add": handler.New(Add), } -Equipped with an Assigner we can now construct a Server: +Equipped with an Assigner we can now construct a [Server]: srv := jrpc2.NewServer(assigner, nil) // nil for default options -To start the server, we need a channel.Channel. Implementations of the Channel -interface handle the framing, transmission, and receipt of JSON messages. The -channel package implements some common framing disciplines for byte streams -like pipes and sockets. +To start the server, we need a [channel.Channel]. Implementations of the +Channel interface handle the framing, transmission, and receipt of JSON +messages. The channel package implements some common framing disciplines for +byte streams like pipes and sockets. For this example, we'll use a channel that communicates over stdin and stdout, with messages delimited by newlines: @@ -83,8 +83,8 @@ example: # Clients -The *Client type implements a JSON-RPC client. A client communicates with a -server over a channel.Channel, and is safe for concurrent use by multiple +The [*Client] type implements a JSON-RPC client. A client communicates with a +server over a [channel.Channel], and is safe for concurrent use by multiple goroutines. It supports batched requests and may have arbitrarily many pending requests in flight simultaneously. @@ -102,7 +102,7 @@ To send a single RPC, use the Call method: rsp, err := cli.Call(ctx, "Math.Add", []int{1, 3, 5, 7}) Call blocks until the response is received. Errors returned by the server have -concrete type *jrpc2.Error. +concrete type [*Error]. To issue a batch of concurrent requests, use the Batch method: @@ -115,7 +115,7 @@ To issue a batch of concurrent requests, use the Batch method: Batch blocks until all the responses are received. An error from the Batch call reflects an error in sending the request: The caller must check each response separately for errors from the server. Responses are returned in the -same order as the Spec values, save that notifications are omitted. +same order as the [Spec] values, save that notifications are omitted. To decode the result from a successful response, use its UnmarshalResult method: @@ -155,15 +155,15 @@ want to do anything for a notification, it can query the request: # Services with Multiple Methods -The example above shows a server with one method. A handler.Map works for any -number of distinctly-named methods: +The example above shows a server with one method. A [handler.Map] works for +any number of distinctly-named methods: mathService := handler.Map{ "Add": handler.New(Add), "Mul": handler.New(Mul), } -Maps may be combined with the handler.ServiceMap type to export multiple +Maps may be combined with the [handler.ServiceMap] type to export multiple services from the same server: func getStatus(context.Context) string { return "all is well" } @@ -182,7 +182,7 @@ require a more complex hierarchy. # Concurrency -A Server issues concurrent requests to handlers in parallel, up to the limit +A [Server] issues concurrent requests to handlers in parallel, up to the limit given by the Concurrency field in ServerOptions. Two requests (either calls or notifications) are concurrent if they arrive as @@ -227,7 +227,7 @@ Otherwise, those methods will report an error: // server push is not enabled } -A method handler may use jrpc2.ServerFromContext to access the server from its +A method handler may use [ServerFromContext] to access the server from its context, and then invoke these methods on it. On the client side, the OnNotify and OnCallback options in jrpc2.ClientOptions provide hooks to which any server requests are delivered, if they are set. @@ -238,7 +238,7 @@ a client response that will never arrive. # Contexts and Cancellation -Both the Server and the Client use the standard context package to plumb +Both the [Server] and the [Client] use the standard context package to plumb cancellation and other request-specific metadata in handlers and calls. On the server, the context passed to a handler is automatically cancelled when @@ -255,7 +255,7 @@ server, as JSON-RPC does not define a standard mechanism to do so. One typical approach (used by LSP, for example) is to define a separate method on the server to handle cancellation requests. -If an OnCancel hook is set in the ClientOptions, the client calls it when the +If an OnCancel hook is set in the [ClientOptions], the client calls it when the context for a Call ends before the server has responded. This can be used to forward cancellation to the server separately. */ diff --git a/error.go b/error.go index ce238d7..3881cb9 100644 --- a/error.go +++ b/error.go @@ -19,7 +19,7 @@ type Error struct { // Error returns a human-readable description of e. func (e Error) Error() string { return fmt.Sprintf("[%d] %s", e.Code, e.Message) } -// ErrCode trivially satisfies the ErrCoder interface for an *Error. +// ErrCode trivially satisfies the [ErrCoder] interface. func (e Error) ErrCode() Code { return e.Code } // WithData marshals v as JSON and constructs a copy of e whose Data field @@ -67,8 +67,7 @@ var errTaskNotExecuted = new(Error) // called after the client connection is closed. var ErrConnClosed = errors.New("client connection is closed") -// Errorf returns an error value of concrete type *Error having the specified -// code and formatted message string. +// Errorf returns an Error with the specified code and formatted message. func Errorf(code Code, msg string, args ...any) *Error { return &Error{Code: code, Message: fmt.Sprintf(msg, args...)} } diff --git a/handler/handler.go b/handler/handler.go index 5658907..3f5d985 100644 --- a/handler/handler.go +++ b/handler/handler.go @@ -1,7 +1,7 @@ // Copyright (C) 2017 Michael J. Fromberger. All Rights Reserved. -// Package handler provides implementations of the jrpc2.Assigner interface, -// and support for adapting functions to jrpc2.Handler signature. +// Package handler provides implementations of the [jrpc2.Assigner] interface, +// and support for adapting functions to [jrpc2.Handler] signature. package handler import ( @@ -19,8 +19,8 @@ import ( // Func is a convenience alias for jrpc2.Handler. type Func = jrpc2.Handler -// A Map is a trivial implementation of the jrpc2.Assigner interface that looks -// up method names in a static map of function values. +// A Map is a trivial implementation of the [jrpc2.Assigner] interface that +// looks up method names in a static map of function values. type Map map[string]jrpc2.Handler // Assign implements part of the jrpc2.Assigner interface. @@ -72,14 +72,14 @@ func (m ServiceMap) Names() []string { return all } -// New adapts a function to a jrpc2.Handler. The concrete value of fn must be -// function accepted by Check. The resulting jrpc2.Handler will handle JSON +// New adapts a function to a [jrpc2.Handler]. The concrete value of fn must be +// function accepted by [Check]. The resulting handler will handle JSON // encoding and decoding, call fn, and report appropriate errors. // // New is intended for use during program initialization, and will panic if the // type of fn does not have one of the accepted forms. Programs that need to -// check for possible errors should call handler.Check directly, and use the -// Wrap method of the resulting FuncInfo to obtain the wrapper. +// check for possible errors should call [Check] directly, and use the Wrap +// method of the resulting [FuncInfo] to obtain the wrapper. func New(fn any) jrpc2.Handler { fi, err := Check(fn) if err != nil { @@ -126,12 +126,12 @@ func (fi *FuncInfo) SetStrict(strict bool) *FuncInfo { fi.strictFields = strict; // value is currently true. This option has no effect for non-struct arguments. func (fi *FuncInfo) AllowArray(ok bool) *FuncInfo { fi.allowArray = ok; return fi } -// Wrap adapts the function represented by fi to a jrpc2.Handler. The wrapped -// function can obtain the *jrpc2.Request value from its context argument using -// the jrpc2.InboundRequest helper. +// Wrap adapts the function represented by fi to a [jrpc2.Handler]. The +// wrapped function can obtain the [*jrpc2.Request] value from its context +// argument using the [jrpc2.InboundRequest] helper. // // This method panics if fi == nil or if it does not represent a valid function -// type. A FuncInfo returned by a successful call to Check is always valid. +// type. A FuncInfo returned by a successful call to [Check] is always valid. func (fi *FuncInfo) Wrap() jrpc2.Handler { if fi == nil || fi.fn == nil { panic("handler: invalid FuncInfo value") @@ -239,9 +239,9 @@ func (fi *FuncInfo) Wrap() jrpc2.Handler { } } -// Check checks whether fn can serve as a jrpc2.Handler. The concrete value of -// fn must be a function with one of the following type signature schemes, for -// JSON-marshalable types X and Y: +// Check checks whether fn can serve as a [jrpc2.Handler]. The concrete value +// of fn must be a function with one of the following type signature schemes, +// for JSON-marshalable types X and Y: // // func(context.Context) error // func(context.Context) Y @@ -277,7 +277,7 @@ func (fi *FuncInfo) Wrap() jrpc2.Handler { // // ... // } // -// For more complex positional signatures, see also handler.Positional. +// For more complex positional signatures, see also [Positional]. func Check(fn any) (*FuncInfo, error) { if fn == nil { return nil, errors.New("nil function") diff --git a/handler/positional.go b/handler/positional.go index de27009..b036361 100644 --- a/handler/positional.go +++ b/handler/positional.go @@ -11,9 +11,9 @@ import ( "github.com/creachadair/jrpc2" ) -// NewPos adapts a function to a jrpc2.Handler. The concrete value of fn must -// be a function accepted by Positional. The resulting handler will handle JSON -// encoding and decoding, call fn, and report appropriate errors. +// NewPos adapts a function to a [jrpc2.Handler]. The concrete value of fn must +// be a function accepted by [Positional]. The resulting handler will handle +// JSON encoding and decoding, call fn, and report appropriate errors. // // NewPos is intended for use during program initialization, and will panic if // the type of fn does not have one of the accepted forms. Programs that need @@ -68,7 +68,7 @@ func structFieldNames(atype reflect.Type) (bool, []string) { return true, names } -// Positional checks whether fn can serve as a jrpc2.Handler. The concrete +// Positional checks whether fn can serve as a [jrpc2.Handler]. The concrete // value of fn must be a function with one of the following type signature // schemes: // @@ -80,12 +80,12 @@ func structFieldNames(atype reflect.Type) (bool, []string) { // forms, Positional reports an error. The given names must match the number of // non-context arguments exactly. Variadic functions are not supported. // -// In contrast to Check, this function allows any number of arguments, but the -// caller must provide names for them. Positional creates an anonymous struct -// type whose fields correspond to the non-context arguments of fn. The names -// are used as the JSON field keys for the corresponding parameters. +// In contrast to [Check], this function allows any number of arguments, but +// the caller must provide names for them. Positional creates an anonymous +// struct type whose fields correspond to the non-context arguments of fn. The +// names are used as the JSON field keys for the corresponding parameters. // -// When converted into a jrpc2.Handler, the wrapped function accepts either a +// When converted into a [jrpc2.Handler], the wrapped function accepts either a // JSON array with exactly n members, or a JSON object with the field keys // named. For example, given: // diff --git a/jhttp/bridge.go b/jhttp/bridge.go index df512c9..0d06b94 100644 --- a/jhttp/bridge.go +++ b/jhttp/bridge.go @@ -15,7 +15,7 @@ import ( "github.com/creachadair/jrpc2/server" ) -// A Bridge is a http.Handler that bridges requests to a JSON-RPC server. +// A Bridge is a [http.Handler] that bridges requests to a JSON-RPC server. // // By default, the bridge accepts only HTTP POST requests with the complete // JSON-RPC request message in the body, with Content-Type application/json. @@ -40,7 +40,7 @@ type Bridge struct { getter *Getter } -// ServeHTTP implements the required method of http.Handler. +// ServeHTTP implements the required method of [http.Handler]. func (b Bridge) ServeHTTP(w http.ResponseWriter, req *http.Request) { // If a GET hook is defined, allow GET requests. if req.Method == "GET" && b.getter != nil { diff --git a/jhttp/channel.go b/jhttp/channel.go index 79a1926..fab5643 100644 --- a/jhttp/channel.go +++ b/jhttp/channel.go @@ -11,8 +11,8 @@ import ( "sync" ) -// A Channel implements a channel.Channel that dispatches requests via HTTP to -// a user-provided URL. Each message sent to the channel is an HTTP POST +// A Channel implements a [channel.Channel] that dispatches requests via HTTP +// to a user-provided URL. Each message sent to the channel is an HTTP POST // request with the message as its body. type Channel struct { url string diff --git a/jhttp/getter.go b/jhttp/getter.go index 58d59c9..f0d66cb 100644 --- a/jhttp/getter.go +++ b/jhttp/getter.go @@ -28,7 +28,7 @@ import ( // Method not found 404 (Not found) // (other errors) 500 (Internal server error) // -// By default, a Getter uses ParseBasic to convert the HTTP request. The URL +// By default, a Getter uses [ParseBasic] to convert the HTTP request. The URL // path identifies the JSON-RPC method, and the URL query parameters are // converted into a JSON object for the parameters. Query values are sent as // JSON strings. For example, this URL: @@ -39,8 +39,8 @@ import ( // // {"param1":"xyzzy", "param2":"apple"} // -// To override the default behaviour, set a ParseRequest hook in GetterOptions. -// See also the jhttp.ParseQuery function for a more expressive translation. +// To override the default behaviour, set a ParseRequest hook in [GetterOptions]. +// See also the [ParseQuery] function for a more expressive translation. type Getter struct { local server.Local parseReq func(*http.Request) (string, any, error) @@ -61,7 +61,7 @@ func NewGetter(mux jrpc2.Assigner, opts *GetterOptions) Getter { } } -// ServeHTTP implements the required method of http.Handler. +// ServeHTTP implements the required method of [http.Handler]. func (g Getter) ServeHTTP(w http.ResponseWriter, req *http.Request) { method, params, err := g.parseHTTPRequest(req) if err != nil { @@ -154,8 +154,8 @@ func writeJSON(w http.ResponseWriter, code int, obj any) { // and parameters. The URL path identifies the method name, with leading and // trailing slashes removed. Query values are packed into a map[string]string. // -// This is the default query parser used by a Getter if none is specified in -// its GetterOptions. +// This is the default query parser used by a [Getter] if none is specified in +// its [GetterOptions]. func ParseBasic(req *http.Request) (string, any, error) { if err := req.ParseForm(); err != nil { return "", nil, err diff --git a/json.go b/json.go index fd17591..227f1c6 100644 --- a/json.go +++ b/json.go @@ -39,8 +39,8 @@ type ParsedRequest struct { Error *Error } -// ToRequest converts p to an equivalent server Request. If p.Error is not nil, -// ToRequest returns nil. +// ToRequest converts p to an equivalent server [Request]. If p.Error is not +// nil, ToRequest returns nil. // // This method does not check validity. If p is from a successful call of // ParseRequests, the result will be valid; otherwise the caller must ensure diff --git a/opts.go b/opts.go index 9c32540..03f831c 100644 --- a/opts.go +++ b/opts.go @@ -11,9 +11,9 @@ import ( "time" ) -// ServerOptions control the behaviour of a server created by NewServer. -// A nil *ServerOptions is valid and provides sensible defaults. -// It is safe to share server options among multiple server instances. +// ServerOptions control the behaviour of a server created by [NewServer]. A +// nil *ServerOptions is valid and provides sensible defaults. It is safe to +// share server options among multiple server instances. type ServerOptions struct { // If not nil, send debug text logs here. Logger Logger @@ -87,7 +87,7 @@ func (s *ServerOptions) rpcLog() RPCLogger { return s.RPCLog } -// ClientOptions control the behaviour of a client created by NewClient. +// ClientOptions control the behaviour of a client created by [NewClient]. // A nil *ClientOptions is valid and provides sensible defaults. type ClientOptions struct { // If not nil, send debug text logs here. @@ -216,8 +216,8 @@ func (lg Logger) Printf(msg string, args ...any) { } } -// StdLogger adapts a *log.Logger to a Logger. If logger == nil, the returned -// function sends logs to the default logger. +// StdLogger adapts a [*log.Logger] to a [Logger]. If logger == nil, the +// returned function sends logs to the default logger. func StdLogger(logger *log.Logger) Logger { if logger == nil { return func(text string) { log.Output(2, text) } diff --git a/server.go b/server.go index 8f81bc4..dacabae 100644 --- a/server.go +++ b/server.go @@ -50,12 +50,12 @@ func init() { // that such changes will affect all servers. // // The caller is responsible for publishing the metrics to the exporter via -// expvar.Publish or similar. +// [expvar.Publish] or similar. func ServerMetrics() *expvar.Map { return serverMetrics } // Server implements a JSON-RPC 2.0 server. The server receives requests and -// sends responses on a channel.Channel provided by the caller, and dispatches -// requests to user-defined Handlers. +// sends responses on a [channel.Channel] provided by the caller, and +// dispatches requests to user-defined Handlers. type Server struct { wg sync.WaitGroup // ready when workers are done at shutdown time mux Assigner // associates method names with handlers @@ -419,9 +419,9 @@ var ErrPushUnsupported = errors.New("server push is not enabled") // // This is a non-standard extension of JSON-RPC, and may not be supported by // all clients. Unless s was constructed with the AllowPush option set true, -// this method will always report an error (ErrPushUnsupported) without sending -// anything. If Notify is called after the client connection is closed, it -// returns ErrConnClosed. +// this method will always report an error ([ErrPushUnsupported]) without +// sending anything. If Notify is called after the client connection is +// closed, it returns [ErrConnClosed]. func (s *Server) Notify(ctx context.Context, method string, params any) error { if !s.allowP { return ErrPushUnsupported @@ -433,7 +433,7 @@ func (s *Server) Notify(ctx context.Context, method string, params any) error { // Callback posts a single server-side call to the client. It blocks until a // reply is received, ctx ends, or the client connection terminates. A // successful callback reports a nil error and a non-nil response. Errors -// returned by the client have concrete type *jrpc2.Error. +// returned by the client have concrete type [*Error]. // // This is a non-standard extension of JSON-RPC, and may not be supported by // all clients. If you are not sure whether the client supports push calls, you @@ -441,9 +441,9 @@ func (s *Server) Notify(ctx context.Context, method string, params any) error { // client response that will never arrive. // // Unless s was constructed with the AllowPush option set true, this method -// will always report an error (ErrPushUnsupported) without sending +// will always report an error ([ErrPushUnsupported]) without sending // anything. If Callback is called after the client connection is closed, it -// returns ErrConnClosed. +// returns [ErrConnClosed]. func (s *Server) Callback(ctx context.Context, method string, params any) (*Response, error) { if !s.allowP { return nil, ErrPushUnsupported diff --git a/server/local.go b/server/local.go index bc73695..05f36b1 100644 --- a/server/local.go +++ b/server/local.go @@ -20,8 +20,8 @@ func (l Local) Close() error { return l.Server.Wait() } -// NewLocal constructs a *jrpc2.Server and a *jrpc2.Client connected to it via -// an in-memory pipe, using the specified assigner and options. +// NewLocal constructs a [*jrpc2.Server] and a [*jrpc2.Client] connected to it +// via an in-memory pipe, using the specified assigner and options. // If opts == nil, it behaves as if the client and server options are also nil. func NewLocal(assigner jrpc2.Assigner, opts *LocalOptions) Local { if opts == nil { @@ -35,7 +35,7 @@ func NewLocal(assigner jrpc2.Assigner, opts *LocalOptions) Local { } // LocalOptions control the behaviour of the server and client constructed by -// the NewLocal function. +// the [NewLocal] function. type LocalOptions struct { Client *jrpc2.ClientOptions Server *jrpc2.ServerOptions diff --git a/server/loop.go b/server/loop.go index d9ea530..213fdb9 100644 --- a/server/loop.go +++ b/server/loop.go @@ -30,7 +30,7 @@ type Service interface { Finish(jrpc2.Assigner, jrpc2.ServerStatus) } -// Static wraps a jrpc2.Assigner to trivially implement the Service interface. +// Static wraps a [jrpc2.Assigner] to trivially implement the Service interface. func Static(m jrpc2.Assigner) func() Service { return static{methods: m}.new } type static struct{ methods jrpc2.Assigner } @@ -47,8 +47,8 @@ type Accepter interface { Accept(ctx context.Context) (channel.Channel, error) } -// NetAccepter adapts a net.Listener to the Accepter interface, using f as the -// channel framing. +// NetAccepter adapts a [net.Listener] to the Accepter interface, using f as +// the channel framing. func NetAccepter(lst net.Listener, f channel.Framing) Accepter { return netAccepter{Listener: lst, newChannel: f} }