use std::path::Path;
use dbmd_core::parser::{extract_sections, read_file, Section};
use crate::cli::SectionsArgs;
use crate::context::Context;
use crate::error::{CliError, CliResult};
pub fn run(ctx: &Context, args: &SectionsArgs) -> CliResult {
let path = Path::new(&args.file);
let (_frontmatter, body) = read_file(path).map_err(|e| map_parse_error(e, &args.file))?;
let sections = extract_sections(&body);
if ctx.json {
print!("{}", sections_json(§ions));
} else {
print!("{}", sections_text(§ions));
}
Ok(())
}
fn sections_text(sections: &[Section]) -> String {
let mut out = String::new();
for s in sections {
let indent = " ".repeat(s.level.saturating_sub(2) as usize);
out.push_str(&format!("{indent}{} (L{})\n", s.heading, s.line));
}
out
}
fn sections_json(sections: &[Section]) -> String {
let arr: Vec<serde_json::Value> = sections
.iter()
.map(|s| {
serde_json::json!({
"heading": s.heading,
"level": s.level,
"line": s.line,
})
})
.collect();
let mut s = serde_json::to_string_pretty(&serde_json::Value::Array(arr))
.unwrap_or_else(|_| "[]".to_string());
s.push('\n');
s
}
fn map_parse_error(err: dbmd_core::ParseError, file: &str) -> CliError {
let core: dbmd_core::Error = err.into();
CliError::from(core).with_hint(format!("could not read sections from `{file}`"))
}