An if let pattern can unpack a successful parse and keep the fallback path explicit.

Program

Play the program to choose raw text and see whether it becomes structured data.

raw
option_destructure.rs
Replay: real traced execution (multi-file project)
fn main() {
    let raw = "cache:3";
    let parsed = parse_pair(raw);
    if let Some((name, count)) = parsed {
        println!("{name}={count}");
    } else {
        println!("invalid");
    }
}

fn parse_pair(text: &str) -> Option<(&str, i32)> {
    let (name, value) = text.split_once(':')?;
    let count = value.parse().ok()?;
    Some((name, count))
}
fn main() {
    let raw = "bad";
    let parsed = parse_pair(raw);
    if let Some((name, count)) = parsed {
        println!("{name}={count}");
    } else {
        println!("invalid");
    }
}

fn parse_pair(text: &str) -> Option<(&str, i32)> {
    let (name, value) = text.split_once(':')?;
    let count = value.parse().ok()?;
    Some((name, count))
}
fn main() {
    let raw = "api:5";
    let parsed = parse_pair(raw);
    if let Some((name, count)) = parsed {
        println!("{name}={count}");
    } else {
        println!("invalid");
    }
}

fn parse_pair(text: &str) -> Option<(&str, i32)> {
    let (name, value) = text.split_once(':')?;
    let count = value.parse().ok()?;
    Some((name, count))
}
  1. raw ← "cache:3"

    1fn main() {2    let ra→ "cache:3"w = "cache:3"; //@raw="cache:3", "bad", "api:5"3    let parsed = parse_pair(ra"cache:3"w);4    if let Some((name, count)) = parsed {
  2. count ← 3

    11fn parse_pair(text: &str) -> Option<(&str, i32)> {12    let (name, value) = text.split_once(':')?;13    let coun→ 3t = value.parse().ok()?;14    Some((nam"cache"e, coun3t))15}
  3. parsed ← Some(("cache", 3))

    2let raw = "cache:3"; //@raw="cache:3", "bad", "api:5"3let parse→ Some(("cache", 3))d = parse_pair(ra"cache:3"w);4if let Some((name, count)) = parsed {
  4. if let Some((name, count)) = parsed

    3let parsed = parse_pair(raw);4if let Some((name, count)) = parsed {5    println!("{name}={count}");6} else {
    outputcache=3
  1. raw ← "bad"

    1fn main() {2    let ra→ "bad"w = "bad";3    let parsed = parse_pair(ra"bad"w);4    if let Some((name, count)) = parsed {
  2. parsed ← None

    2    let raw = "bad";3    let parse→ Noned = parse_pair(ra"bad"w);4    if let Some((name, count)) = parsed {5        println!("{name}={count}");6    } else {7        println!("invalid");8    }9}1011fn parse_pair(text: &str) -> Option<(&str, i32)> {12    let (name, value) = text.split_once(':')?;13    let count = value.parse().ok()?;
  3. else

    5    println!("{name}={count}");6} else {7    println!("invalid");8}
    outputinvalid
  1. raw ← "api:5"

    1fn main() {2    let ra→ "api:5"w = "api:5";3    let parsed = parse_pair(ra"api:5"w);4    if let Some((name, count)) = parsed {
  2. count ← 5

    11fn parse_pair(text: &str) -> Option<(&str, i32)> {12    let (name, value) = text.split_once(':')?;13    let coun→ 5t = value.parse().ok()?;14    Some((nam"api"e, coun5t))15}
  3. parsed ← Some(("api", 5))

    2let raw = "api:5";3let parse→ Some(("api", 5))d = parse_pair(ra"api:5"w);4if let Some((name, count)) = parsed {
  4. if let Some((name, count)) = parsed

    3let parsed = parse_pair(raw);4if let Some((name, count)) = parsed {5    println!("{name}={count}");6} else {
    outputapi=5
if let `if let Some((name, count))` handles the success shape directly.
question mark `?` returns `None` early when splitting or parsing fails.
tuple pattern `(name, count)` destructures both fields from the successful result.