Skip to content

Commit 449bf44

Browse files
committed
refactor(usage_md): return custom error type instead of calling process::exit
Define a non-exhaustive `RenderUsageMdError` enum with `derive_more::{Display, Error}` and make `render_usage_md` return `Result<String, RenderUsageMdError>`. The callsites in cli/usage_md.rs and tests/sync_usage_md.rs now handle the error appropriately. https://claude.ai/code/session_01TSnvxN1HBwwzhxfFShWAQ5
1 parent 96d8729 commit 449bf44

3 files changed

Lines changed: 27 additions & 18 deletions

File tree

cli/usage_md.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
use parallel_disk_usage::usage_md::render_usage_md;
22

33
fn main() {
4-
println!("{}", render_usage_md().trim_end());
4+
match render_usage_md() {
5+
Ok(content) => println!("{}", content.trim_end()),
6+
Err(error) => {
7+
eprintln!("error: {error}");
8+
std::process::exit(1);
9+
}
10+
}
511
}

src/usage_md.rs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
use crate::args::Args;
22
use clap::builder::PossibleValue;
33
use clap::{Arg, ArgAction, Command, CommandFactory};
4+
use derive_more::{Display, Error};
45
use itertools::Itertools;
56
use std::borrow::Cow;
67

8+
/// Error produced when generating the usage Markdown.
9+
#[derive(Debug, Display, Error)]
10+
#[non_exhaustive]
11+
pub enum RenderUsageMdError {
12+
/// A `visible_alias` or `visible_short_alias` duplicates the argument's own flag name.
13+
#[display("redundant visible alias: {_0}")]
14+
RedundantVisibleAlias(#[error(not(source))] String),
15+
}
16+
717
/// Renders a Markdown reference page for `pdu`'s CLI.
8-
pub fn render_usage_md() -> String {
18+
pub fn render_usage_md() -> Result<String, RenderUsageMdError> {
919
let mut command: Command = Args::command();
10-
validate_no_redundant_visible_aliases(&command);
20+
validate_no_redundant_visible_aliases(&command)?;
1121
let mut out = String::new();
1222

1323
let usage = command.render_usage().to_string();
@@ -60,7 +70,7 @@ pub fn render_usage_md() -> String {
6070
}
6171
}
6272

63-
out
73+
Ok(out)
6474
}
6575

6676
fn render_argument(out: &mut String, arg: &Arg) {
@@ -239,35 +249,28 @@ fn ensure_ends_with_punctuation(line: &str) -> Cow<'_, str> {
239249
/// A `visible_alias` matching the argument's own `--long` name, or a `visible_short_alias`
240250
/// matching its own `-short` flag, is a coding mistake that produces redundant output in
241251
/// USAGE.md. This function detects such mistakes and terminates the process.
242-
fn validate_no_redundant_visible_aliases(command: &Command) {
243-
let mut errors = Vec::<String>::new();
244-
252+
fn validate_no_redundant_visible_aliases(command: &Command) -> Result<(), RenderUsageMdError> {
245253
for arg in command.get_arguments() {
246254
if let Some(primary_long) = arg.get_long() {
247255
for alias in arg.get_visible_aliases().unwrap_or_default() {
248256
if alias == primary_long {
249-
errors.push(format!(
257+
return Err(RenderUsageMdError::RedundantVisibleAlias(format!(
250258
"--{primary_long} has visible_alias \"{alias}\" that duplicates its own flag name",
251-
));
259+
)));
252260
}
253261
}
254262
}
255263

256264
if let Some(primary_short) = arg.get_short() {
257265
for alias in arg.get_visible_short_aliases().unwrap_or_default() {
258266
if alias == primary_short {
259-
errors.push(format!(
267+
return Err(RenderUsageMdError::RedundantVisibleAlias(format!(
260268
"-{primary_short} has visible_short_alias '{alias}' that duplicates its own flag name",
261-
));
269+
)));
262270
}
263271
}
264272
}
265273
}
266274

267-
if !errors.is_empty() {
268-
for error in &errors {
269-
eprintln!("error: {error}");
270-
}
271-
std::process::exit(1);
272-
}
275+
Ok(())
273276
}

tests/sync_usage_md.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use parallel_disk_usage::usage_md::render_usage_md;
1111

1212
#[test]
1313
fn usage_md() {
14-
let actual = render_usage_md();
14+
let actual = render_usage_md().expect("render_usage_md failed");
1515
let expected = include_str!("../USAGE.md");
1616
assert!(
1717
actual.trim_end() == expected.trim_end(),

0 commit comments

Comments
 (0)