0Pricing
Learn Rust Coding · Lesson

Validation and Help

Polished CLIs.

Validation and Help is a free Learn Rust Coding lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Learn Rust Coding learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Polishing your CLI

A great CLI validates input early and offers clear help. clap supports both with attributes and value parsers.

  • Reject bad values with friendly messages
  • Document every argument

Value ranges

Restrict a numeric argument to a range with value_parser. Out-of-range input is rejected automatically.

use clap::Parser;

#[derive(Parser)]
struct Cli {
    #[arg(long, value_parser = clap::value_parser!(u16).range(1..=65535))]
    port: u16,
}

Enumerated choices

Use #[derive(ValueEnum)] to constrain an argument to a fixed set of strings.

use clap::{Parser, ValueEnum};

#[derive(Clone, ValueEnum)]
enum Mode { Fast, Safe }

#[derive(Parser)]
struct Cli {
    #[arg(long, value_enum)]
    mode: Mode,
}

Custom validation function

Pass a function to value_parser that returns Result. clap turns an Err into a usage error.

fn parse_even(s: &str) -> Result<u32, String> {
    let n: u32 = s.parse().map_err(|_| "not a number".to_string())?;
    if n % 2 == 0 { Ok(n) } else { Err("must be even".to_string()) }
}

Trying validation logic

The validation function is plain Rust. Run it to see how an even/odd check returns Ok or Err.

fn parse_even(s: &str) -> Result<u32, String> {
    let n: u32 = s.parse().map_err(|_| "not a number".to_string())?;
    if n % 2 == 0 { Ok(n) } else { Err("must be even".to_string()) }
}

fn main() {
    println!("{:?}", parse_even("4"));
    println!("{:?}", parse_even("7"));
}

Required groups and conflicts

Express relationships between args. conflicts_with stops two incompatible flags being used together.

use clap::Parser;

#[derive(Parser)]
struct Cli {
    #[arg(long)]
    quiet: bool,
    #[arg(long, conflicts_with = "quiet")]
    verbose: bool,
}

Help text per field

A doc comment above a field becomes its help text. This is the idiomatic way to document arguments.

use clap::Parser;

#[derive(Parser)]
struct Cli {
    /// The file to process
    input: String,
}

Long help vs short help

clap shows a short summary for -h and the full text for --help. Split them with #[arg(short_help, long_help)] when needed.

use clap::Parser;

#[derive(Parser)]
struct Cli {
    #[arg(long, long_help = "A detailed explanation shown only with --help")]
    flag: bool,
}

Returning Result from main

For runtime errors after parsing, return Result from main. The ? operator propagates errors and clap-free programs print them with a non-zero exit.

fn main() -> Result<(), String> {
    let value = "42";
    let n: i32 = value.parse().map_err(|_| "bad number".to_string())?;
    println!("parsed {}", n);
    Ok(())
}

Custom error styling

clap formats usage errors automatically, but you can build your own with clap::Error and cmd.error() for context-specific messages.

use clap::{CommandFactory, Parser};

#[derive(Parser)]
struct Cli { value: i32 }

fn fail() {
    let mut cmd = Cli::command();
    cmd.error(clap::error::ErrorKind::ValueValidation, "value too large").exit();
}

Validation summary in plain Rust

The essence of CLI validation is checking a value and reporting a clear error. Here it is end to end.

fn validate_port(p: u32) -> Result<u32, String> {
    if (1..=65535).contains(&p) { Ok(p) }
    else { Err(format!("port {} out of range", p)) }
}

fn main() {
    match validate_port(8080) {
        Ok(p) => println!("using port {}", p),
        Err(e) => eprintln!("error: {}", e),
    }
}

Quick Check

Test your understanding of validation and help.

Recap

You can now build polished CLIs:

  • value_parser enforces ranges and custom rules
  • ValueEnum limits choices
  • conflicts_with models incompatible flags
  • Doc comments become help text
  • Return Result from main for runtime errors

That completes the clap course.

Frequently asked questions

Is the “Validation and Help” lesson free?

Yes — the full text of “Validation and Help” is free to read here on the web, and the Learn Rust Coding course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Learn Rust Coding course, upgrade to CoddyKit PRO.

What will I learn in “Validation and Help”?

Polished CLIs. You practise Learn Rust Coding with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Learn Rust Coding?

No prior experience is required. Learn Rust Coding on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Validation and Help” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Learn Rust Coding lesson?

Yes. Every Learn Rust Coding lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. clap Basics
  2. Subcommands
  3. Derive API
  4. Validation and Help
← Back to Learn Rust Coding