Frrist/bind command simplify#23
Merged
Merged
Conversation
Now that command.Command is valid-by-construction, parsing and segment
construction belong to the command package, not binding. binding.Parse and
binding.New only re-did command.Parse/command.New and wrapped the result, so
drop both in favour of a single Bind(cmd command.Command) constructor that
pairs an already-valid command with its typed Args/OK. Bind cannot fail, so it
returns no error.
Callers compose explicitly, e.g.
binding.Bind[*Args, *OK](command.MustParse("/x/y")).
The client path (Bind/Invoke/Unpack) was well documented but the symmetric server path was not: Request, Response, NewRequest, HandlerFunc, the option constructors, and the error helpers had no doc comments. Fill those in and expand the package overview with the canonical declaration pattern and the three handler-registration paths (server.NewRoute, Binding.Handler/NewHandler, raw execution.HandlerFunc). Add runnable examples that render on the package docs: binding.Example covers the full client/server round trip, and server.ExampleNewRoute shows bundling commands with handlers as Routes and registering them.
execution.WithProofs and binding.WithProofs were byte-for-byte identical to their package's WithDelegations, giving callers two names for one behavior. Delete both and keep WithDelegations as the single name, folding in the "should be linked from the invocation" note. Migrate the example callers. invocation.WithProofs is unrelated (it takes delegation links to populate a UCAN's prf field) and is left untouched.
type EventListener = any gave consumers no signal about what to implement; the contract lived only in optional single-method interfaces probed by runtime type-assertion. Redefine EventListener (on both server and client) as the composition of its side's two capability interfaces — the io.ReadWriteCloser idiom — so the type states its full contract. The emit methods now call the methods directly instead of type-asserting.
frrist
commented
May 21, 2026
Comment on lines
-48
to
-59
| // New creates a binding from the provided command segments. | ||
| func New[Args, OK CBORValue](segments ...string) Binding[Args, OK] { | ||
| return Binding[Args, OK]{Command: command.New(segments...)} | ||
| } | ||
|
|
||
| // Parse verifies that s is a well-formed command and returns its binding. | ||
| func Parse[Args, OK CBORValue](s string) (Binding[Args, OK], error) { | ||
| cmd, err := command.Parse(s) | ||
| if err != nil { | ||
| return Binding[Args, OK]{}, err | ||
| } | ||
| return Binding[Args, OK]{Command: cmd}, nil |
frrist
commented
May 21, 2026
Comment on lines
+70
to
79
| // Bind pairs an already-valid command with the Go types of its arguments | ||
| // (Args) and result (OK). The command carries its own validity (it cannot be | ||
| // constructed except through command.Parse, command.MustParse, or | ||
| // command.New), so Bind cannot fail. Construct or parse the command with the | ||
| // command package, then attach its types here: | ||
| // | ||
| // b := binding.Bind[*Args, *OK](command.MustParse("/space/info")) | ||
| func Bind[Args, OK CBORValue](cmd command.Command) Binding[Args, OK] { | ||
| return Binding[Args, OK]{Command: cmd} | ||
| } |
Member
Author
There was a problem hiding this comment.
Package is now closer to its intended use. It binds a command to its arguments and return value only. This entire package is pure sugar.
frrist
commented
May 21, 2026
Comment on lines
-9
to
+15
| type EventListener = any | ||
| // EventListener observes both halves of the request/response round trip a | ||
| // client performs: a request being encoded and a response being decoded. | ||
| // Register one with [WithEventListener]. | ||
| type EventListener interface { | ||
| RequestEncodeListener | ||
| ResponseDecodeListener | ||
| } |
Member
Author
There was a problem hiding this comment.
Makes this a little easier to use.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
WithProofscall. Though one remains in/ucan/invocation/options.gotype EventListener = anywith an interface, and removes come asstions it