1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
#![cfg_attr(feature = "type_inequality_hack", feature(associated_const_equality))]
#![cfg_attr(feature = "type_inequality_hack", feature(const_type_id))]
//! Rust enums are coproducts but the datastructure provided in this library
//! allows writing functions that operate on generic coproducts.
//!
//! For instance, the below function takes any coproduct that may contain a cat.
//! ```
//! # use coproduct::{Coproduct, Count, IndexedDrop};
//! # struct Cat;
//! fn is_cat<C, I>(maybe_cat: C) -> bool
//! where
//! C: coproduct::At<I, Cat>,
//! {
//! maybe_cat.uninject().is_ok()
//! }
//! ```
//!
//! The coproducts take as much memory as the largest variant and 32 bits
//! for the tag, which is pretty close to optimal. They do not benefit from
//! Rust's enum layout optimizations, but the whole reason for this crate is
//! that those optimizations aren't perfect. Implementing a coproduct as nested
//! enums akin to a purely functional list results in extremely high memory use.
//! (Tested in Rust 1.66)
//!
//! Another benefit is that the implementation of some functions is a lot simpler
//! when there is no need to pretend that a nested structure is traversed. The
//! downside is that unlike the coproduct provided by frunk, this library uses
//! unsafe.
mod coproduct;
mod count;
mod public_traits;
mod union;
pub use crate::coproduct::*;
pub use count::*;
pub use public_traits::*;
pub use union::{EmptyUnion, Union};
#[cfg(feature = "type_inequality_hack")]
mod type_inequality;
#[cfg(feature = "type_inequality_hack")]
pub use type_inequality::NotEqual;
#[cfg(feature = "type_inequality_hack")]
pub mod merge;
#[cfg(feature = "type_inequality_hack")]
pub use merge::Merge;