Skip to main content

acta_build/
lib.rs

1//! Build-time helper for [acta](https://crates.io/crates/acta).
2//!
3//! Call from your `build.rs` to compute a sensible default `path_width` for
4//! `acta::Formatter` based on the longest source-file path in your project.
5//!
6//! # Example
7//!
8//! Add to your `Cargo.toml`:
9//!
10//! ```toml
11//! [build-dependencies]
12//! acta-build = "0.1"
13//! ```
14//!
15//! In `build.rs`:
16//!
17//! ```no_run
18//! # fn example() {
19//! let width = acta_build::walk_src_max_width("src", "src/");
20//! println!("cargo:rustc-env=ACTA_PATH_WIDTH={width}");
21//! println!("cargo:rerun-if-changed=src");
22//! # }
23//! ```
24//!
25//! Then in your code:
26//!
27//! ```ignore
28//! let width: usize = env!("ACTA_PATH_WIDTH").parse().unwrap_or(40);
29//! let formatter = acta::Formatter::new().with_path_width(width);
30//! ```
31
32use std::path::Path;
33use walkdir::WalkDir;
34
35/// Walk `dir` recursively, find every `.rs` file, and return
36/// `max(path_len_after_stripping(strip_prefix)) + 4`.
37///
38/// Returns 40 if `dir` does not exist or contains no .rs files
39#[must_use]
40pub fn walk_src_max_width(dir: impl AsRef<Path>, strip_prefix: &str) -> usize {
41    WalkDir::new(dir.as_ref())
42        .into_iter()
43        .filter_map(Result::ok)
44        .filter(|e| e.path().extension().is_some_and(|ext| ext == "rs"))
45        .map(|e| {
46            let display = e.path().to_string_lossy().replace('\\', "/");
47            display.strip_prefix(strip_prefix).unwrap_or(&display).len()
48        })
49        .max()
50        .map_or(40, |max| max + 4)
51}