Unify typed binding preparation

This commit is contained in:
2026-10-11 01:18:07 +00:00
parent de9bfdcc4c
commit f63b096525
5 changed files with 130 additions and 65 deletions

View File

@@ -58,12 +58,21 @@ type Flag[I any] struct {
binding flagBinding[I]
}
type bindingIdentity struct{ marker byte }
type preparedValue[I any] struct {
identity *bindingIdentity
supplied bool
apply func(*I)
}
type flagBinding[I any] struct {
identity *bindingIdentity
meta FlagMeta
defaultText string
repeated bool
boolean bool
prepare func([]string) (func(*I), error)
prepare func([]string) (preparedValue[I], error)
clear func(*I)
valid bool
}
@@ -74,11 +83,12 @@ type Argument[I any] struct {
}
type argumentBinding[I any] struct {
meta ArgumentMeta
min int
max int
prepare func([]string) (func(*I), error)
valid bool
identity *bindingIdentity
meta ArgumentMeta
min int
max int
prepare func([]string) (preparedValue[I], error)
valid bool
}
// CommandSpec declares one command using typed input and handler callbacks.
@@ -319,7 +329,7 @@ func validateBindings[I any](flags []Flag[I], arguments []Argument[I]) error {
}
shortNames[binding.meta.Short] = struct{}{}
}
if !binding.valid || binding.prepare == nil {
if binding.identity == nil || !binding.valid || binding.prepare == nil {
return fmt.Errorf("flag %q is missing parser or setter wiring", binding.meta.Name)
}
}
@@ -332,7 +342,7 @@ func validateBindings[I any](flags []Flag[I], arguments []Argument[I]) error {
if binding.min < 0 || binding.max < -1 || (binding.max >= 0 && binding.min > binding.max) {
return fmt.Errorf("argument %q has invalid bounds %d..%d", binding.meta.Name, binding.min, binding.max)
}
if !binding.valid || binding.prepare == nil {
if binding.identity == nil || !binding.valid || binding.prepare == nil {
return fmt.Errorf("argument %q is missing parser or setter wiring", binding.meta.Name)
}
}