#![cfg(feature = "docs")]
use std::path::PathBuf;
use crate::core::ApiError;
use crate::docs::{generate_docs, write_docs, DocFormat};
const FORMAT_VALUES: &[&str] = &["openapi", "swagger", "cli-markdown", "mcp-markdown", "all"];
pub fn docs_subcommand_definition() -> clap::Command {
clap::Command::new("docs")
.about("Generate documentation files")
.arg(
clap::Arg::new("format")
.long("format")
.value_parser(clap::builder::PossibleValuesParser::new(FORMAT_VALUES))
.default_value("all")
.help("Documentation format"),
)
.arg(
clap::Arg::new("output")
.long("output")
.value_parser(clap::value_parser!(PathBuf))
.help("Output file path (stdout if omitted)"),
)
}
fn parse_format(s: &str) -> DocFormat {
match s {
"openapi" => DocFormat::OpenApi,
"swagger" => DocFormat::SwaggerUi,
"cli-markdown" => DocFormat::CliMarkdown,
"mcp-markdown" => DocFormat::McpMarkdown,
"all" => DocFormat::All,
_ => unreachable!("clap value_parser 已限定输入集合,得到非法值: {}", s),
}
}
pub fn docs_subcommand(matches: &clap::ArgMatches) -> Result<(), ApiError> {
let format_str = matches
.get_one::<String>("format")
.map(|s| s.as_str())
.unwrap_or("all");
let format = parse_format(format_str);
match matches.get_one::<PathBuf>("output") {
Some(path) => write_docs(format, path)
.map_err(|e| ApiError::internal_with_source("docs write failed", "docs_subcommand", e)),
None => {
let content = generate_docs(format)
.map_err(|e| ApiError::internal_with_source("docs generation failed", "docs_subcommand", e))?;
println!("{}", content);
Ok(())
}
}
}