use crate::cli::{
argv::Event,
command::{ArgumentState, Command, Key},
};
#[derive(Debug, Clone)]
pub struct HandlerSchemas {
pub result: schemars::Schema,
pub error: schemars::Schema,
}
pub trait HandlerResult {
fn schemas(generator: &mut schemars::SchemaGenerator) -> HandlerSchemas;
}
impl<T, E> HandlerResult for Result<T, E>
where
T: schemars::JsonSchema,
E: schemars::JsonSchema,
{
fn schemas(generator: &mut schemars::SchemaGenerator) -> HandlerSchemas {
let mut result = generator.subschema_for::<T>();
result
.ensure_object()
.entry("title".to_owned())
.or_insert_with(|| serde_json::Value::String(T::schema_name().into_owned()));
let mut error = generator.subschema_for::<E>();
error
.ensure_object()
.entry("title".to_owned())
.or_insert_with(|| serde_json::Value::String(E::schema_name().into_owned()));
HandlerSchemas { result, error }
}
}
pub trait HandlerSchemaSource: InvocableCommandHandler {
#[doc(hidden)]
fn handler_schemas(generator: &mut schemars::SchemaGenerator) -> HandlerSchemas;
}
pub trait InvocableCommandHandler: CommandArgs {}
pub trait CommandArgs: Sized {
type Partial;
const COMMAND: &'static Command<'static>;
const SCHEMA_ENABLED: bool = false;
#[doc(hidden)]
fn schema_registry() -> Option<crate::__private::SchemaRegistry> {
None
}
fn start() -> Self::Partial;
fn apply(partial: &mut Self::Partial, event: &Event<'_, '_>) -> bool;
fn argument_state(partial: &Self::Partial, key: Key) -> Option<ArgumentState>;
fn check_constraints(partial: &Self::Partial) -> Result<(), crate::Error>;
fn check_occurrences(partial: &mut Self::Partial) -> Result<(), crate::Error>;
fn check_required(partial: &mut Self::Partial) -> Result<(), crate::Error>;
fn check(partial: &mut Self::Partial) -> Result<(), crate::Error> {
Self::check_occurrences(partial)?;
Self::check_required(partial)?;
Self::check_constraints(partial)
}
fn finish(partial: Self::Partial) -> Result<Self, crate::Error>;
}
#[doc(hidden)]
pub trait Args: CommandArgs {}
pub trait Subcommands: Sized {
type Partial;
const COMMANDS: &'static [&'static Command<'static>];
fn start() -> Self::Partial;
fn selected(partial: &Self::Partial) -> bool;
fn apply(partial: &mut Self::Partial, event: &Event<'_, '_>) -> bool;
fn check_occurrences(partial: &mut Self::Partial) -> Result<(), crate::Error>;
fn check_required(partial: &mut Self::Partial) -> Result<(), crate::Error>;
fn check_constraints(partial: &Self::Partial) -> Result<(), crate::Error>;
fn finish(partial: Self::Partial) -> Result<Option<Self>, crate::Error>;
}