use anyhow::Result;
#[cfg(feature = "metadata")]
#[derive(Debug, Clone, serde::Serialize)]
pub struct CommandParamMeta {
pub name: &'static str,
pub r#type: &'static str,
}
#[cfg(feature = "metadata")]
#[derive(Debug, Clone, serde::Serialize)]
pub struct CommandMeta {
pub name: &'static str,
pub is_async: bool,
pub style: &'static str,
pub params: &'static [CommandParamMeta],
pub return_type: &'static str,
}
pub struct CommandRegistration {
pub register: fn() -> Result<()>,
#[cfg(feature = "metadata")]
pub meta: CommandMeta,
}
inventory::collect!(CommandRegistration);
#[cfg(feature = "metadata")]
#[macro_export]
#[doc(hidden)]
macro_rules! __submit_registration {
($reg_fn:ident, $meta:expr) => {
$crate::inventory::submit! {
$crate::CommandRegistration {
register: $reg_fn,
meta: $meta,
}
}
};
}
#[cfg(not(feature = "metadata"))]
#[macro_export]
#[doc(hidden)]
macro_rules! __submit_registration {
($reg_fn:ident, $meta:expr) => {
$crate::inventory::submit! {
$crate::CommandRegistration {
register: $reg_fn,
}
}
};
}
pub fn reg_all_commands() -> Result<()> {
for reg in inventory::iter::<CommandRegistration> {
(reg.register)()?;
}
Ok(())
}
#[cfg(feature = "metadata")]
pub fn get_all_command_metas() -> Vec<&'static CommandMeta> {
inventory::iter::<CommandRegistration>
.into_iter()
.map(|reg| ®.meta)
.collect()
}
#[cfg(feature = "metadata")]
pub fn export_commands_json<P: AsRef<std::path::Path>>(path: P) -> Result<()> {
let metas = get_all_command_metas();
let json = serde_json::to_string_pretty(&metas)?;
std::fs::write(path, json)?;
Ok(())
}