either-or-both

Crates.ioeither-or-both
lib.rseither-or-both
version0.2.0
created_at2025-08-27 16:43:10.417882+00
updated_at2025-08-28 13:15:35.772755+00
descriptionThe enums EitherOrBoth with the three variants Left, Right, Both and Either with the Left and Right variants
homepagehttps://github.com/gamma0987/either-or-both
repositoryhttps://github.com/gamma0987/either-or-both
max_upload_size
id1812938
size392,598
(gamma0987)

documentation

README

EitherOrBoth and Either

Released API Docs | Changelog

GitHub branch checks state Coverage Crates.io docs.rs

either-or-both provides two enums: Either and EitherOrBoth.

  • Either<L, R> — a value that is either Left(L) or Right(R)
  • EitherOrBoth<L, R> — a value that can be Left(L), Right(R), or Both(L, R)

While Either is useful for representing mutually exclusive values, EitherOrBoth extends this idea by allowing both values to be present simultaneously.

Why Use EitherOrBoth and Either?

If you often write code like this:

match options {
    (Some(left), Some(right)) => println!("Left is: {left}, Right is: {right}"),
    (Some(left), None) => println!("Left is: {left}"),
    (None, Some(right)) => println!("Right is: {right}"),
    (None, None) => unreachable!("Should not happen"),
}

You can simplify and clarify your intent using EitherOrBoth:

  • Removes boilerplate
  • Improves readability
  • Eliminates unreachable patterns at compile time

Abstracting over multiple types with Either:

Suppose you have a function that returns either an in-memory reader or a file-backed one:

fn get_reader(path: Option<&str>) -> Either<Cursor<Vec<u8>>, File> {
    match path {
        Some(p) => Either::Right(File::open(p).unwrap()),
        None => Either::Left(Cursor::new(vec![1, 2, 3])),
    }
}

This allows you to return different types under a single unified interface (e.g. both implement Read), without boxing or trait objects.

Use Either when:

  • You want to represent one of two meaningful values
  • You're modeling branching logic that's not necessarily an error case
  • You need to return different types while keeping the API ergonomic and type-safe

Features

  • Intuitive API inspired by Option and functional programming patterns
  • Includes combinators like bimap, map, and_then, apply, etc.
  • #![no_std] compatible (when the std feature is disabled)
  • Fully documented on docs.rs

Installation

Add either-or-both to your Cargo.toml:

[dependencies]
either-or-both = "0.2.0"

Or use cargo add:

cargo add either-or-both@0.2.0

Design Philosophy

The API for either-or-both is heavily inspired by the Option type from the Rust standard library and aims for consistency between the Either and EitherOrBoth enums. Some methods, like bimap, are derived from functional programming languages. Where applicable, methods from Option are also implemented for both Either and EitherOrBoth. Whenever possible, method names with similar functionality are shared across both enums. If you're familiar with the Option API, you'll find the EitherOrBoth and Either interface intuitive and easy to work with.

Development Status

The core API is production-ready.

However, as long as the crate version is below 1.0.0, semver guarantees do not apply — minor version bumps may include breaking changes.

License

either-or-both is dual licensed under the Apache 2.0 license and the MIT license at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you shall be dual licensed as in License, without any additional terms or conditions.

Commit count: 93

cargo fmt