use std::path::PathBuf;
use clap::{Parser, ValueEnum};
#[derive(Parser, Debug)]
#[command(name = "docspec")]
#[command(version = "0.1.0")]
#[command(
about = "Convert documents between formats using streaming event pipeline",
long_about = "Convert documents between formats using streaming event pipeline.\n\nSupports converting Markdown or HTML input to BlockNote JSON output.\n\nNote: the HTML reader currently parses only <p> paragraph elements and\nthe text within them. All other HTML elements (headings, lists, tables,\nformatting, etc.) are silently dropped. Use Markdown input for full\nfeature coverage."
)]
pub struct Cli {
#[arg(long, value_name = "WHEN", default_value = "auto")]
pub color: ColorChoice,
#[arg(short, long)]
pub from: Option<CliInputFormat>,
#[arg(value_name = "FILE")]
pub input: Option<PathBuf>,
#[arg(short, long, value_name = "FILE")]
pub output: Option<PathBuf>,
#[arg(short, long)]
pub to: Option<CliOutputFormat>,
}
#[derive(Clone, Copy, Debug, ValueEnum)]
pub enum ColorChoice {
#[value(name = "always")]
Always,
#[value(name = "auto")]
Auto,
#[value(name = "never")]
Never,
}
#[derive(Clone, Copy, Debug, ValueEnum)]
pub enum CliInputFormat {
#[value(name = "html")]
Html,
#[value(name = "markdown")]
Markdown,
}
#[derive(Clone, Copy, Debug, ValueEnum)]
pub enum CliOutputFormat {
#[value(name = "blocknote")]
Blocknote,
#[value(name = "oxa")]
Oxa,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn clap_rejects_blocknote_as_input() {
let result = Cli::try_parse_from(["docspec", "--from", "blocknote", "x.md"]);
assert!(
result.is_err(),
"blocknote should not be a valid input format"
);
}
#[test]
fn clap_rejects_markdown_as_output() {
let result = Cli::try_parse_from(["docspec", "--to", "markdown", "x.md"]);
assert!(
result.is_err(),
"markdown should not be a valid output format"
);
}
#[test]
fn clap_accepts_oxa_as_output_format() {
let result = Cli::try_parse_from(["docspec", "--to", "oxa", "x.md"]);
assert!(
result.is_ok(),
"oxa should be a valid output format, got error: {:?}",
result.as_ref().err()
);
let cli = result.unwrap_or_else(|_| std::process::abort());
assert!(
matches!(cli.to, Some(CliOutputFormat::Oxa)),
"expected CliOutputFormat::Oxa, got {:?}",
cli.to
);
}
}