use super::{render_refs, write_expanded_rendered_md};
use crate::config::Config;
use crate::diagnostic::DiagnosticResult;
use crate::model::{AdrEntry, AlternativeStatus};
use crate::signature::{compute_adr_signature, format_signature_header};
use std::fmt::Write as FmtWrite;
pub fn render_adr(adr: &AdrEntry) -> DiagnosticResult<String> {
let meta = adr.meta();
let content = &adr.spec.content;
let mut out = String::new();
let signature = compute_adr_signature(adr)?;
out.push_str(&format_signature_header(&meta.id, &signature));
let _ = writeln!(out);
let _ = writeln!(out, "# {}: {}", meta.id, meta.title);
let _ = writeln!(out);
let _ = writeln!(
out,
"> **Status:** {} | **Date:** {}",
meta.status.as_ref(),
meta.date
);
if let Some(ref by) = meta.superseded_by {
let _ = writeln!(out, "> **Superseded by:** {by}");
}
let _ = writeln!(out);
if !meta.tags.is_empty() {
let _ = writeln!(out, "> **Tags:** `{}`", meta.tags.join("`, `"));
let _ = writeln!(out);
}
if !meta.refs.is_empty() {
let _ = writeln!(out, "**References:** {}", render_refs(&meta.refs));
let _ = writeln!(out);
}
let _ = writeln!(out, "## Context");
let _ = writeln!(out);
let _ = writeln!(out, "{}", content.context);
let _ = writeln!(out);
let _ = writeln!(out, "## Decision");
let _ = writeln!(out);
let _ = writeln!(out, "{}", content.decision);
let _ = writeln!(out);
let _ = writeln!(out, "## Consequences");
let _ = writeln!(out);
let _ = writeln!(out, "{}", content.consequences);
let _ = writeln!(out);
if !content.alternatives.is_empty() {
let _ = writeln!(out, "## Alternatives Considered");
let _ = writeln!(out);
for alt in &content.alternatives {
let status_suffix = match alt.status {
AlternativeStatus::Considered => "",
AlternativeStatus::Accepted => " (accepted)",
AlternativeStatus::Rejected => " (rejected)",
};
let _ = writeln!(out, "### {}{}", alt.text, status_suffix);
let _ = writeln!(out);
if !alt.pros.is_empty() {
let _ = writeln!(out, "- **Pros:** {}", alt.pros.join(", "));
}
if !alt.cons.is_empty() {
let _ = writeln!(out, "- **Cons:** {}", alt.cons.join(", "));
}
if let Some(ref reason) = alt.rejection_reason {
let _ = writeln!(out, "- **Rejected because:** {}", reason);
}
let _ = writeln!(out);
}
}
Ok(out)
}
pub fn write_adr_md(config: &Config, adr: &AdrEntry, dry_run: bool) -> DiagnosticResult<()> {
let meta = adr.meta();
let output_path = config.adr_output().join(format!("{}.md", meta.id));
let raw = render_adr(adr)?;
write_expanded_rendered_md(config, &output_path, &raw, dry_run, 15)
}