use std::sync::Arc;
use serde_json::{Map, Value};
use crate::ctx::Ctx;
use crate::errors;
use crate::spec::JsonMap;
use crate::spec::command::{CliHints, HTTPHints, MCPHints};
use crate::spec::field::FieldMeta;
use crate::spec::schema::Schema;
pub struct Entry {
pub name: String,
pub summary: String,
pub description: String,
pub input_schema: Schema,
pub output_schema: Option<Schema>,
pub root: FieldMeta,
pub cli: CliHints,
pub http: HTTPHints,
pub mcp: MCPHints,
#[allow(clippy::type_complexity)]
pub invoke: Box<dyn Fn(&Ctx, &JsonMap) -> errors::Result<Value> + Send + Sync>,
}
impl std::fmt::Debug for Entry {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Entry")
.field("name", &self.name)
.field("input_schema", &self.input_schema)
.field("output_schema", &self.output_schema)
.field("cli", &self.cli)
.field("http", &self.http)
.field("mcp", &self.mcp)
.finish()
}
}
impl Entry {
pub(crate) fn _ty() {}
pub fn cli_defaults(&self) -> Map<String, Value> {
transport_defaults(&self.root, |f| f.cli.default.clone())
}
pub fn http_defaults(&self) -> Map<String, Value> {
transport_defaults(&self.root, |f| f.http.default.clone())
}
pub fn mcp_defaults(&self) -> Map<String, Value> {
transport_defaults(&self.root, |f| f.mcp.default.clone())
}
}
fn transport_defaults(
node: &FieldMeta,
get: impl Fn(&FieldMeta) -> Option<Value> + Copy,
) -> Map<String, Value> {
let mut out = Map::new();
for f in &node.children {
if f.skip {
continue;
}
if let Some(d) = get(f) {
out.insert(f.json_name.clone(), d);
}
}
out
}
pub type SharedEntry = Arc<Entry>;