use crate::{Command, CommandGlobalOpts};
use async_trait::async_trait;
use clap::Args as ClapArgs;
use miette::Result;
use ockam_node::Context;
use std::sync::Arc;
#[async_trait]
pub trait CommandsParser<C>: Clone
where
C: ClapArgs,
{
fn parse_commands(self, overrides: &ValuesOverrides) -> Result<Vec<C>>;
}
pub struct ParsedCommands {
pub commands: Vec<Arc<dyn ParsedCommand>>,
}
impl ParsedCommands {
pub fn new<C: ParsedCommand + Send + 'static>(commands: Vec<C>) -> Self {
ParsedCommands {
commands: commands
.into_iter()
.map(|c| {
let b: Arc<dyn ParsedCommand> = Arc::new(c);
b
})
.collect::<Vec<Arc<dyn ParsedCommand>>>(),
}
}
pub async fn run(self, ctx: &Context, opts: &CommandGlobalOpts) -> Result<()> {
for cmd in self.commands.into_iter() {
if cmd.is_valid(ctx, opts).await? {
cmd.run(ctx, opts).await?;
opts.terminal.write_line("")?;
}
}
Ok(())
}
}
impl<C: Command> From<Vec<C>> for ParsedCommands {
fn from(cmds: Vec<C>) -> ParsedCommands {
ParsedCommands::new(cmds)
}
}
#[async_trait]
pub trait ParsedCommand: Send + Sync + 'static {
async fn is_valid(&self, ctx: &Context, opts: &CommandGlobalOpts) -> Result<bool>;
async fn run(&self, ctx: &Context, opts: &CommandGlobalOpts) -> Result<()>;
}
#[async_trait]
impl<C> ParsedCommand for C
where
C: Command + Clone + Send + Sync + 'static,
{
async fn is_valid(&self, _ctx: &Context, _opts: &CommandGlobalOpts) -> Result<bool> {
Ok(true)
}
async fn run(&self, ctx: &Context, opts: &CommandGlobalOpts) -> Result<()> {
self.clone().async_run(ctx, opts.clone()).await
}
}
struct EmptyParsedCommand;
#[async_trait]
impl ParsedCommand for EmptyParsedCommand {
async fn run(&self, _ctx: &Context, _opts: &CommandGlobalOpts) -> Result<()> {
Ok(())
}
async fn is_valid(&self, _ctx: &Context, _opts: &CommandGlobalOpts) -> Result<bool> {
Ok(false)
}
}
#[derive(Debug, Clone, Default)]
pub struct ValuesOverrides {
pub override_node_name: Option<String>,
}
impl ValuesOverrides {
pub fn with_override_node_name(mut self, node_name: &str) -> Self {
self.override_node_name = Some(node_name.to_string());
self
}
}