| Crates.io | clap-sort |
| lib.rs | clap-sort |
| version | 1.0.3 |
| created_at | 2025-11-02 15:27:03.335148+00 |
| updated_at | 2025-11-03 13:29:19.251693+00 |
| description | Validate that clap Subcommand enums are sorted alphabetically |
| homepage | https://github.com/jdx/clap-sort |
| repository | https://github.com/jdx/clap-sort |
| max_upload_size | |
| id | 1913227 |
| size | 34,531 |
A Rust library to validate that clap Subcommand enums are sorted alphabetically.
When using clap's derive API, it's a good practice to keep subcommands sorted alphabetically for easier maintenance and better UX. This crate helps enforce that convention by validating the clap Command structure at runtime.
Add to your Cargo.toml:
[dev-dependencies]
clap-sort = "0.1"
The best way to use clap-sort is to add a unit test to your CLI project:
#[cfg(test)]
mod tests {
use clap::CommandFactory;
#[test]
fn test_subcommands_are_sorted() {
let cmd = cli::Cli::command();
clap_sort::assert_sorted(&cmd);
}
}
This approach ensures that:
cargo testuse clap::{Parser, Subcommand};
#[derive(Parser)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Add, // ✓ Sorted
Delete, // ✓ Sorted
List, // ✓ Sorted
}
#[cfg(test)]
mod tests {
use super::*;
use clap::CommandFactory;
#[test]
fn verify_cli_sorted() {
clap_sort::assert_sorted(&Cli::command());
}
}
If you prefer Result-based error handling:
use clap::CommandFactory;
#[test]
fn test_subcommands() {
let cmd = Cli::command();
match clap_sort::is_sorted(&cmd) {
Ok(()) => println!("Commands are sorted!"),
Err(msg) => panic!("{}", msg),
}
}
The library validates the runtime Command structure by:
CommandThis approach works with both the builder API and derive API, and validates the actual command structure as clap sees it.
#[derive(Subcommand)]
enum Commands {
Add,
Delete,
List,
}
#[derive(Subcommand)]
enum Commands {
#[command(name = "add")]
AddCmd,
#[command(name = "delete")]
DeleteCmd,
#[command(name = "list")]
ListCmd,
}
#[derive(Subcommand)]
enum Commands {
List, // Should be third
Add, // Should be first
Delete, // Should be second
}
Run the test suite:
cargo test
The library includes comprehensive tests covering:
Here's a complete example showing how unsorted commands are caught:
use clap::{Parser, Subcommand};
#[derive(Parser)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
List, // ❌ Should be third
Add, // ❌ Should be first
Delete, // ❌ Should be second
}
#[cfg(test)]
mod tests {
use super::*;
use clap::CommandFactory;
#[test]
fn test_sorted() {
clap_sort::assert_sorted(&Cli::command());
}
}
When you run cargo test, this will fail with:
thread 'tests::test_sorted' panicked at 'Subcommands are not sorted alphabetically!
Actual order: ["list", "add", "delete"]
Expected order: ["add", "delete", "list"]'
MIT or Apache-2.0 (your choice)