use lifeloop::{AdapterManifest, lookup_manifest, manifest_registry};
use serde::Serialize;
use super::{CliError, print_json};
#[derive(Serialize)]
struct ManifestSummary<'a> {
adapter_id: &'a str,
adapter_version: &'a str,
display_name: &'a str,
conformance: lifeloop::ConformanceLevel,
}
pub fn run<I: Iterator<Item = String>>(mut args: I) -> Result<(), CliError> {
let action = args.next().ok_or_else(|| {
CliError::Usage("manifest requires a subcommand: list | show | inspect".to_string())
})?;
match action.as_str() {
"list" => run_list(args),
"show" => run_show(args),
"inspect" => run_inspect(args),
other => Err(CliError::Usage(format!(
"manifest: unknown subcommand `{other}` (expected: list | show | inspect)"
))),
}
}
fn run_list<I: Iterator<Item = String>>(mut args: I) -> Result<(), CliError> {
if args.next().is_some() {
return Err(CliError::Usage(
"manifest list: unexpected extra argument".into(),
));
}
let registry = manifest_registry();
let summaries: Vec<ManifestSummary<'_>> = registry
.iter()
.map(|entry| ManifestSummary {
adapter_id: &entry.manifest.adapter_id,
adapter_version: &entry.manifest.adapter_version,
display_name: &entry.manifest.display_name,
conformance: entry.conformance,
})
.collect();
print_json(&summaries)
}
fn run_show<I: Iterator<Item = String>>(mut args: I) -> Result<(), CliError> {
let id = args
.next()
.ok_or_else(|| CliError::Usage("manifest show requires an <adapter_id>".into()))?;
if args.next().is_some() {
return Err(CliError::Usage(
"manifest show: unexpected extra argument".into(),
));
}
let entry = lookup_manifest(&id)
.ok_or_else(|| CliError::Validation(format!("manifest show: unknown adapter_id `{id}`")))?;
print_json::<AdapterManifest>(&entry.manifest)
}
fn run_inspect<I: Iterator<Item = String>>(mut args: I) -> Result<(), CliError> {
let spec = args.next().ok_or_else(|| {
CliError::Usage("manifest inspect requires <adapter_id>@<version>".into())
})?;
if args.next().is_some() {
return Err(CliError::Usage(
"manifest inspect: unexpected extra argument".into(),
));
}
let (id, version) = spec.split_once('@').ok_or_else(|| {
CliError::Usage(format!(
"manifest inspect: expected <adapter_id>@<version>, got `{spec}`"
))
})?;
let entry = lookup_manifest(id).ok_or_else(|| {
CliError::Validation(format!("manifest inspect: unknown adapter_id `{id}`"))
})?;
if entry.manifest.adapter_version != version {
return Err(CliError::Validation(format!(
"manifest inspect: adapter `{id}` is registered at version `{}`, not `{version}`",
entry.manifest.adapter_version
)));
}
print_json::<AdapterManifest>(&entry.manifest)
}