use alloc::boxed::Box;
use alloc::string::String;
use alloc::vec::Vec;
use core::fmt;
use crate::Result;
use crate::io::{BoxFuture, Io};
#[derive(Clone, Copy)]
pub struct Args<'a> {
parts: &'a [String],
}
impl<'a> Args<'a> {
pub(crate) fn new(parts: &'a [String]) -> Self {
Args { parts }
}
pub fn len(&self) -> usize {
self.parts.len()
}
pub fn is_empty(&self) -> bool {
self.parts.is_empty()
}
pub fn get(&self, i: usize) -> Option<&str> {
self.parts.get(i).map(|s| s.as_str())
}
pub fn iter(&self) -> impl Iterator<Item = &str> {
self.parts.iter().map(|s| s.as_str())
}
pub fn rest(&self) -> String {
let mut out = String::new();
for (i, part) in self.parts.iter().enumerate() {
if i > 0 {
out.push(' ');
}
out.push_str(part);
}
out
}
}
impl fmt::Debug for Args<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.parts).finish()
}
}
pub(crate) type Handler<'a> =
Box<dyn for<'x> Fn(Args<'x>, Io<'x>) -> BoxFuture<'x, Result<()>> + 'a>;
pub(crate) type Completer<'a> = Box<dyn Fn(usize, &str) -> Vec<String> + 'a>;
pub(crate) enum CompleterKind<'a> {
Options(&'static [&'static str]),
Custom(Completer<'a>),
}
pub(crate) struct Command<'a> {
pub name: String,
pub help: &'static str,
pub handler: Handler<'a>,
pub completer: Option<CompleterKind<'a>>,
}