#convert #options #either #erasure

no-std option_either_or

Option into Either conversion

1 stable release

1.0.0 Aug 13, 2025

#2891 in Rust patterns

Download history 14/week @ 2025-11-06 6/week @ 2025-11-13 6/week @ 2025-11-27 12/week @ 2025-12-04 5/week @ 2026-01-22 9/week @ 2026-01-29 48/week @ 2026-02-05 41/week @ 2026-02-12 32/week @ 2026-02-19

131 downloads per month

MIT/Apache

9KB

option_either_or

Crates.io License Crates.io Version GitHub branch check runs docs.rs

Convert Option<T> into Either<L, T>.

Overview

This crate introduces either_or and either_or_else to Option in order to facilitate conversions from Option to Either.

It is mainly useful as generalizations of unwrap_or/unwrap_or_else where the provided default value is of a different type than the Some variant, but both types implement some common trait.

Examples

You can take advantage of Either implementing Display to provide a default value to Option<String> without allocating another string...

use option_either_or::OptionEitherOr as _;
let x = Some(String::from("string"));
let y = x.either_or("default");
println!("{y}");

... or provide defaults to impl Display (or any other trait generically implemented by Either) in a generic context...

fn transform(x: Option<impl Display>) -> impl Display {
    use option_either_or::OptionEitherOr as _;

    x.either_or_else(|| "default")
}

... or even provide defaults to a generic Future, like so:

use std::{future::Pending, time::Duration};

use option_either_or::OptionEitherOr;

async fn await_or_sleep(f: Option<impl Future<Output = ()>>) {
    f.either_or_else(|| async move {
        println!("doing nothing by default and sleeping...");
        tokio::time::sleep(Duration::from_secs(1)).await;
        println!("...slept");
    })
    .await
}

#[tokio::main]
async fn main() {
    await_or_sleep(Some(async move {
        for _ in 0..4 {
            println!("something real");
            tokio::time::sleep(Duration::from_millis(100)).await;
        }
    }))
    .await;

    println!("---");

    await_or_sleep(Option::<Pending<()>>::None).await;
}

Dependencies

~42KB