#![doc = include_str!("../README.md")]
#![cfg_attr(nightly, feature(doc_cfg))]
use std::{collections::HashMap, error::Error};
#[cfg_attr(nightly, doc(cfg(feature = "async")))]
#[cfg(feature = "async")]
use std::{future::Future, pin::Pin};
mod cli;
mod command;
pub mod error;
mod prelude;
pub use clik_codegen::*;
pub type Fn<T> = fn(&mut T, Vec<String>) -> Result<(), Box<dyn Error>>;
#[cfg_attr(nightly, doc(cfg(feature = "async")))]
#[cfg(feature = "async")]
pub type AsyncFn<T> = fn(
&mut T,
Vec<String>,
) -> Pin<Box<dyn Future<Output = Result<(), Box<dyn Error>>> + Send + '_>>;
pub enum FnType<T> {
Sync(Fn<T>),
#[cfg_attr(nightly, doc(cfg(feature = "async")))]
#[cfg(feature = "async")]
Async(AsyncFn<T>),
}
pub struct CLI<'a, T: Send> {
state: T,
commands: HashMap<&'a str, Command<'a, T>>,
}
impl<'a, T: Send> CLI<'_, T> {
pub fn new(state: T) -> Self {
Self {
state,
commands: HashMap::new(),
}
}
}
pub struct Command<'a, T> {
name: &'a str,
help: &'a str,
callback: FnType<T>,
subcommands: HashMap<&'a str, Command<'a, T>>,
}
impl<'a, T: Send> Command<'a, T> {
pub fn new(name: &'a str, help: &'a str, callback: Fn<T>) -> Self {
Self {
name,
help,
callback: FnType::Sync(callback),
subcommands: HashMap::new(),
}
}
#[cfg_attr(nightly, doc(cfg(feature = "async")))]
#[cfg(feature = "async")]
pub fn new_async(name: &'a str, help: &'a str, callback: AsyncFn<T>) -> Self {
Self {
name,
help,
callback: FnType::Async(callback),
subcommands: HashMap::new(),
}
}
}