#[non_exhaustive]pub struct RuntimeCommandSpec {
pub spec: CommandSpec,
pub handler: CommandHandler,
pub streaming_handler: Option<StreamingCommandHandler>,
}Expand description
Executable leaf command.
RuntimeCommandSpec pairs a CommandSpec with async business logic.
This split keeps metadata inspectable for help/search/schema generation
before the handler ever runs.
Use RuntimeCommandSpec::new_streaming for commands that emit incremental
NDJSON progress events (e.g. long-running deployments with --follow).
Construct with one of the new* constructors — never as a struct literal.
Literal construction would bypass the handles_dry_run/handler-shape
misuse checks those constructors debug-assert. #[non_exhaustive] also
means the engine can add fields without a breaking release.
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.spec: CommandSpecDeclarative command metadata.
handler: CommandHandlerAsync command implementation.
streaming_handler: Option<StreamingCommandHandler>Optional streaming handler. When set, the engine writes NDJSON events to stdout as they arrive instead of collecting a single envelope.
Implementations§
Source§impl RuntimeCommandSpec
impl RuntimeCommandSpec
Sourcepub fn new<F, Fut, Output>(spec: CommandSpec, handler: F) -> Self
pub fn new<F, Fut, Output>(spec: CommandSpec, handler: F) -> Self
Creates a runtime command with the common handler shape.
The handler receives a lazy CredentialResolver and the effective args.
Call resolver.resolve().await? only when the command actually needs a
credential; commands that ignore it never trigger an auth flow. The
handler returns CommandResult, where data must be JSON-serializable.
This handler shape has no CommandContext, so it can never call
CommandContext::dry_run — do not pair this with
CommandSpec::handles_dry_run (debug-asserted; see that field’s docs).
Sourcepub fn new_with_context<F, Fut, Output>(spec: CommandSpec, handler: F) -> Selfwhere
F: Fn(CommandContext) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Result<Output>> + Send + 'static,
Output: Into<CommandResult> + Send + 'static,
pub fn new_with_context<F, Fut, Output>(spec: CommandSpec, handler: F) -> Selfwhere
F: Fn(CommandContext) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Result<Output>> + Send + 'static,
Output: Into<CommandResult> + Send + 'static,
Creates a runtime command with the full invocation context.
Sourcepub fn new_streaming<F, Fut>(spec: CommandSpec, handler: F) -> Selfwhere
F: Fn(CommandContext, StreamSender) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Result<()>> + Send + 'static,
pub fn new_streaming<F, Fut>(spec: CommandSpec, handler: F) -> Selfwhere
F: Fn(CommandContext, StreamSender) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Result<()>> + Send + 'static,
Creates a streaming command that emits NDJSON events to stdout.
The handler receives context and a StreamSender. It should call
sender.send(event).await for each progress event, then return Ok(()).
The engine writes each event as a JSON line; stdout is flushed after each.
Sourcepub fn new_typed<T, F, Fut, Output>(spec: CommandSpec, handler: F) -> Selfwhere
T: FromArgMatches + Send + 'static,
F: Fn(CredentialResolver, T) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Result<Output>> + Send + 'static,
Output: Into<CommandResult> + Send + 'static,
pub fn new_typed<T, F, Fut, Output>(spec: CommandSpec, handler: F) -> Selfwhere
T: FromArgMatches + Send + 'static,
F: Fn(CredentialResolver, T) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Result<Output>> + Send + 'static,
Output: Into<CommandResult> + Send + 'static,
Creates a runtime command with typed argument deserialization.
The handler receives a lazy CredentialResolver and the deserialized
args struct. Use with CommandSpec::from_args::<T>() to get end-to-end
type safety from argument definition through handler consumption.
If the handler also needs the command path, middleware, or user-supplied
args, use RuntimeCommandSpec::new_typed_with_context (or
RuntimeCommandSpec::new_with_context with
CommandContext::typed_args) instead.
This handler shape has no CommandContext, so it can never call
CommandContext::dry_run — do not pair this with
CommandSpec::handles_dry_run (debug-asserted; see that field’s docs).
Sourcepub fn new_typed_with_context<T, F, Fut, Output>(
spec: CommandSpec,
handler: F,
) -> Selfwhere
T: FromArgMatches + Send + 'static,
F: Fn(CommandContext, T) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Result<Output>> + Send + 'static,
Output: Into<CommandResult> + Send + 'static,
pub fn new_typed_with_context<T, F, Fut, Output>(
spec: CommandSpec,
handler: F,
) -> Selfwhere
T: FromArgMatches + Send + 'static,
F: Fn(CommandContext, T) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Result<Output>> + Send + 'static,
Output: Into<CommandResult> + Send + 'static,
Creates a runtime command with full context and typed argument deserialization.
Combines new_with_context’s
access to CommandContext (command path, middleware snapshot,
user-supplied args, CommandContext::dry_run) with
new_typed’s automatic
deserialization: the engine parses T from the raw matches before
invoking the handler, so the handler never needs to call
CommandContext::typed_args itself.
Use this instead of new_with_context + context.typed_args::<T>()
when a command needs full context and wants eager, guaranteed-parsed
typed args rather than parsing on demand. Because the handler receives
a CommandContext, this is a valid pairing with
CommandSpec::handles_dry_run.
§Errors
The returned handler surfaces a CliCoreError::Message if T fails to
deserialize from the parsed matches (this should not happen for args
generated by CommandSpec::from_args::<T>(), since clap already
validated them during parsing).
Sourcepub fn new_typed_streaming<T, F, Fut>(spec: CommandSpec, handler: F) -> Selfwhere
T: FromArgMatches + Send + 'static,
F: Fn(CommandContext, T, StreamSender) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Result<()>> + Send + 'static,
pub fn new_typed_streaming<T, F, Fut>(spec: CommandSpec, handler: F) -> Selfwhere
T: FromArgMatches + Send + 'static,
F: Fn(CommandContext, T, StreamSender) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Result<()>> + Send + 'static,
Creates a streaming command with full context and typed argument deserialization.
Combines new_streaming’s NDJSON
event emission with new_typed’s
automatic deserialization: the engine parses T from the raw matches
before invoking the handler.
§Errors
The returned handler surfaces a CliCoreError::Message if T fails to
deserialize from the parsed matches.
Trait Implementations§
Source§impl Clone for RuntimeCommandSpec
impl Clone for RuntimeCommandSpec
Source§fn clone(&self) -> RuntimeCommandSpec
fn clone(&self) -> RuntimeCommandSpec
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more