Either

A general-purpose Left/Right sum type for Rust with Iterator, Read, and Write support

Library
Cargo
v1.17.0
563stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
64/100Good
Development Activity72
Maintenance36
Community68
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
75/100Good
Architecture75
Code Quality78
Innovation65
Learning Curve80

Either provides the Either<L, R> enum, a general-purpose sum type with two symmetric variants, Left and Right. Unlike Result, which implies success/failure semantics, Either treats both variants equally, making it useful whenever a value can be one of two unrelated types without an inherent notion of correctness or error.

The crate goes well beyond a bare enum: it implements standard traits like Iterator, Read, Write, Future, Deref, and Error for Either whenever both variants implement them, so code that branches on a runtime condition can still be written generically against a single type. It also ships convenience macros (for_both!, try_left!, try_right!, map_both!) and optional serde support (including untagged serialization modules), all while remaining #![no_std]-compatible by default.

What You Get

  • The Either<L, R> enum with Left and Right variants and dozens of combinator methods mirroring Option/Result (map_left, map_right, left_or, factor_first, etc.)
  • Blanket trait implementations for Iterator, Read, Write, Seek, Future, Deref/DerefMut, AsRef/AsMut, and std::error::Error whenever both variants implement them
  • Convenience macros for_both!, map_both!, try_left!, and try_right! for branch-agnostic and short-circuiting code
  • Optional serde support, including serde_untagged and serde_untagged_optional modules for customizing how Either fields serialize
  • #![no_std] support by default, with an opt-in std feature for Read/Write/Error implementations

Common Use Cases

  • Returning one of two different response/body types from a function without wrapping them in a boxed trait object
  • Writing code generic over two concrete iterator, reader, or writer types by relying on Either’s blanket trait forwarding
  • Modeling configuration or CLI values that can be supplied in two different formats (e.g. a path or an inline value)
  • Serializing/deserializing untagged two-variant fields in JSON or other serde-based formats

Under The Hood

Architecture - The crate centers on a single Either<L, R> enum defined in src/lib.rs (roughly 1,800 lines), with satellite modules iterator.rs (Iterator trait forwarding), into_either.rs (the IntoEither conversion trait), and serde_untagged.rs/serde_untagged_optional.rs for opt-in untagged serde support. Rather than a layered architecture, the design is a single flat surface: one enum plus a large set of inherent methods and trait impls that forward operations to whichever variant is active, keeping the mental model simple even as the surface area grows.

Tech Stack - Written in pure Rust with edition = "2021" and an MSRV of 1.63, the crate has exactly one dependency (serde, optional and default-features-disabled) and one dev-dependency (serde_json). It supports #![no_std] by default, gating std-only trait impls (Read/Write/Seek/Error) behind an opt-in std feature, which keeps it usable in embedded and other constrained environments.

Code Quality - Tests live inline in lib.rs (7 #[test] functions covering core combinator behavior) rather than in a separate integration-test directory; the satellite modules (iterator.rs, into_either.rs, serde modules) have no dedicated unit tests of their own, relying on doctest examples embedded throughout the public API instead. Naming is consistent and mirrors Option/Result conventions closely (map_left/map_right, left_or, unwrap_left), which lowers the learning curve for anyone already familiar with the standard library.

API Design - The public API is highly ergonomic specifically because it rhymes with Option and Result: users familiar with those types can guess most of Either’s method names correctly. Getting started requires zero configuration beyond either = "1" in Cargo.toml, and the crate’s docs.rs page plus inline doctests provide runnable examples for nearly every non-trivial method, minimizing the need to read source code to use the crate correctly.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search