adrs_core/lib.rs
1//! # adrs-core
2//!
3//! The engine behind the [`adrs`] command-line tool: a standalone library for
4//! creating, reading, linking, validating, and exporting Architecture Decision
5//! Records (ADRs).
6//!
7//! Depend on `adrs-core` directly when you want to manage ADRs from your own
8//! program -- a build tool, an editor integration, or an AI agent -- instead of
9//! shelling out to the CLI. The CLI is a thin layer over this crate, so anything
10//! `adrs` does is available here as a normal Rust API.
11//!
12//! [`adrs`]: https://crates.io/crates/adrs
13//!
14//! ## Key types
15//!
16//! - [`Repository`] -- the main entry point. Open or initialize a directory of
17//! ADRs, then [`list`](Repository::list), [`new_adr`](Repository::new_adr),
18//! [`link`](Repository::link), [`supersede`](Repository::supersede), and
19//! [`set_status`](Repository::set_status).
20//! - [`Adr`] -- a single decision record: number, title, [`AdrStatus`], body
21//! sections, [`AdrLink`]s, tags, and MADR metadata (deciders, consulted,
22//! informed).
23//! - [`AdrStatus`] and [`LinkKind`] -- typed status values and link
24//! relationships (e.g. `Supersedes` / `SupersededBy`).
25//! - [`Config`] and [`discover`] -- repository configuration and upward
26//! directory discovery (find the ADR directory from a nested path).
27//! - [`Parser`] -- parse an ADR from markdown, in either legacy (adr-tools) or
28//! YAML-frontmatter form.
29//! - The [`export`] module -- convert ADRs to and from the **JSON-ADR**
30//! interchange format, handy for feeding a decision log to other tools or to
31//! an AI agent that reasons over it.
32//! - The [`lint`] module -- repository health checks via [`check_all`]:
33//! broken links, duplicate numbers, numbering gaps, and missing fields.
34//! - [`Error`] and [`Result`] -- the library's error type, built on `thiserror`.
35//!
36//! ## Modes
37//!
38//! ADRs can be stored in two on-disk formats:
39//!
40//! - **Compatible mode** (default): markdown-only, interoperable with
41//! [adr-tools]. Reads both legacy and next-gen files; writes legacy.
42//! - **Next-gen mode**: YAML frontmatter for structured metadata, enabling
43//! richer features like typed links, tags, and stronger validation.
44//!
45//! The mode is chosen at [`Repository::init`] time (the `ng` argument) or via
46//! [`Config`], and the parser transparently reads either format.
47//!
48//! [adr-tools]: https://github.com/npryce/adr-tools
49//!
50//! ## Quick start
51//!
52//! ```
53//! use adrs_core::Repository;
54//!
55//! # fn main() -> adrs_core::Result<()> {
56//! # let tmp = tempfile::tempdir().unwrap();
57//! // Initialize a repository (compatible mode).
58//! let repo = Repository::init(tmp.path(), None, false)?;
59//!
60//! // Create a decision record.
61//! let (adr, _path) = repo.new_adr("Use PostgreSQL for persistence")?;
62//! assert_eq!(adr.title, "Use PostgreSQL for persistence");
63//!
64//! // List all ADRs (`init` seeds the first one).
65//! let all = repo.list()?;
66//! assert!(all.len() >= 2);
67//! # Ok(())
68//! # }
69//! ```
70//!
71//! ## Exporting to JSON-ADR
72//!
73//! [`export_repository`] converts an open [`Repository`] to the JSON-ADR format.
74//! For a plain directory that isn't an initialized adrs repository, use
75//! [`export_directory`] (or [`export_directory_with_warnings`] to also receive a
76//! message for every file that failed to parse, rather than skipping silently).
77//!
78//! ## More examples
79//!
80//! The [`examples`](https://github.com/joshrotenberg/adrs/tree/main/crates/adrs-core/examples)
81//! directory has runnable programs: `create_and_list`, `link_adrs`,
82//! `export_json`, and `lint_repository`.
83
84mod config;
85pub mod doctor;
86mod error;
87pub mod export;
88pub mod lint;
89mod parse;
90mod repository;
91mod template;
92mod types;
93
94pub use config::{Config, ConfigMode, ConfigSource, DiscoveredConfig, discover};
95pub use error::{Error, Result};
96pub use export::{
97 ConsideredOption, ImportOptions, ImportResult, JSON_ADR_SCHEMA, JSON_ADR_VERSION, JsonAdr,
98 JsonAdrBulkExport, JsonAdrLink, JsonAdrSingle, RepositoryInfo, ToolInfo, export_adr,
99 export_directory, export_directory_with_warnings, export_repository, import_to_directory,
100};
101pub use lint::{Issue, IssueSeverity, LintReport, check_all, check_repository, lint_adr, lint_all};
102pub use parse::Parser;
103pub use repository::Repository;
104pub use template::{Template, TemplateEngine, TemplateFormat, TemplateVariant};
105pub use types::{Adr, AdrLink, AdrStatus, LinkKind};
106
107// Legacy doctor module - deprecated, use lint module instead
108#[deprecated(since = "0.6.0", note = "Use lint module instead")]
109pub use doctor::{Check, Diagnostic, DoctorReport, Severity, check as doctor_check};