prim_fmt/lib.rs
1//! The prim formatting engine.
2//!
3//! prim is an opinionated, near-zero-config formatter for a repository's
4//! connective tissue — Markdown, JSON/JSONC, YAML, TOML — plus whitespace
5//! hygiene on a curated set of un-owned text files.
6//!
7//! The engine has two steps:
8//!
9//! 1. [`classify`] decides whether prim owns a file (by name/extension) and, if
10//! so, what [`FileKind`] it is. Files prim does not own are left untouched.
11//! 2. [`format`] applies the canonical formatting for that kind.
12//!
13//! [`format`] applies structured canonicalisation to the parsed formats —
14//! JSON/JSONC via `dprint-plugin-json`, TOML via `taplo`, YAML via
15//! `pretty_yaml`, Markdown via `dprint-plugin-markdown` — followed by the
16//! format-agnostic **whitespace hygiene** pass (trailing-whitespace removal,
17//! single final line-feed, configured line endings). `Orphan` files receive
18//! hygiene only.
19
20mod classify;
21mod error;
22mod hygiene;
23mod json;
24mod markdown;
25mod style;
26mod toml;
27mod yaml;
28
29pub use classify::{FileKind, classify};
30pub use error::FormatError;
31pub use style::{Indent, LineEnding, Style};
32
33/// Format `source` as the given [`FileKind`] under `style`.
34///
35/// Returns [`FormatError`] when a structured format cannot be parsed; the CLI
36/// then leaves the file unchanged and reports it (FR-6.3). The `match` is the
37/// dispatch point where structured per-format passes (FR-1) attach.
38pub fn format(kind: FileKind, source: &str, style: &Style) -> Result<String, FormatError> {
39 match kind {
40 FileKind::Json | FileKind::Jsonc => json::format(source, style),
41 FileKind::Toml => toml::format(source, style),
42 FileKind::Yaml => yaml::format(source, style),
43 FileKind::Markdown => markdown::format(source, style),
44 FileKind::Orphan => Ok(hygiene::hygiene(source, style)),
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51
52 #[test]
53 fn hygiene_kinds_return_ok() {
54 let style = Style::default();
55 assert_eq!(format(FileKind::Orphan, "x \n", &style).unwrap(), "x\n");
56 assert_eq!(format(FileKind::Markdown, "a\r\n", &style).unwrap(), "a\n");
57 }
58}