Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Error Handling

Every fallible constructor returns IsinError on failure. It’s Clone + PartialEq + Eq, and it implements both core::error::Error and core::fmt::Display, so it composes cleanly with ? and with error-aggregation crates (anyhow, thiserror, eyre, and friends).

Variants

VariantWhen it occurs
EmptyThe input string was empty.
InvalidLengthAfter trimming surrounding whitespace, the input didn’t contain exactly 12 characters (carries the count found).
InvalidCharacterA character outside the allowed set appeared at a given position (carries the character, 1-indexed position, and the expected character class).
InvalidCheckDigitThe ISO 6166 Luhn check digit at position 12 didn’t match (carries the expected and found digits).

The expected character class is one of Letter (positions 1–2), Alphanumeric (positions 3–11), or Digit (position 12).

Matching on specific failures

Reach for a match when you need to react differently to different failure modes. For example, turning a specific error into a targeted field-level message for a form, rather than just surfacing the generic Display text:

use ftracker_identifiers::{Isin, IsinError};

match Isin::parse(user_input) {
    Ok(isin) => save(isin),
    Err(IsinError::Empty) => reject("ISIN is required"),
    Err(IsinError::InvalidLength { found }) => {
        reject(&format!("expected 12 characters, found {found}"))
    }
    Err(IsinError::InvalidCharacter { character, position, .. }) => {
        reject(&format!("unexpected '{character}' at position {position}"))
    }
    Err(IsinError::InvalidCheckDigit { expected, found }) => {
        reject(&format!("check digit looks wrong: expected {expected}, found {found}"))
    }
}

Just want a message?

If you don’t need to distinguish between failure modes, IsinError’s Display implementation already produces a human-readable message, so ? and .to_string() work as expected:

use ftracker_identifiers::Isin;

fn parse_isin(input: &str) -> Result<Isin, String> {
    Isin::parse(input).map_err(|e| e.to_string())
}

Untrusted input is always re-validated

This matters most when the serde feature is enabled: deserializing an Isin from JSON, YAML, or any other serde format re-runs the exact same validation as Isin::parse. There is no serialization shortcut that could let an invalid value slip through; see Feature Flags.