quither/lib.rs
1// Copyright 2021 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! "Quad-state Either": Quither. In other words, either-or-neither-or-both type.
16//!
17//! Quither is a type that represents four states:
18//! - `Left(L)`
19//! - `Right(R)`
20//! - `Both(L, R)`
21//! - `Neither`
22//!
23//! This crate also provides an arbitrary combination types of `Either`, `Neither`, and `Both`.
24//! For example, `EitherOrBoth<L, R>` is a type that represents either a left (`Left(L)`) or right (`Right(R)`) or both (`Both(L, R)`).
25//! These types have consistent APIs (as much as possible ☺) so that you can use them interchangeably.
26//!
27//! Each combination types implements the common methods greedily, even if it's not very useful for that type itself.
28//! For example, `EitherOrNeither` type implements `is_both()` method, even if it always returns `false`.
29//!
30
31#![cfg_attr(not(feature = "use_std"), no_std)]
32
33mod and_or_getters;
34mod as_ref;
35mod conv;
36mod factor;
37mod get_or_insert;
38mod getters;
39mod into;
40pub mod iter;
41mod map;
42mod std_impls;
43
44// Pair types, essentially comibinations of `Either`, `Neither`, and `Both`.
45
46/// An enum that represents either a left (`Left(L)`) or right (`Right(R)`) value.
47#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
48pub enum Either<L, R> {
49 Left(L),
50 Right(R),
51}
52
53/// An enum that represents a single `Neither` value.
54#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
55pub enum Neither {
56 Neither,
57}
58
59/// An enum that represents a pair of values (`Both(L, R)`).
60#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
61pub enum Both<L, R> {
62 Both(L, R),
63}
64
65/// An enum that represents either a left (`Left(L)`) or right (`Right(R)`) or neither (`Neither`).
66#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
67pub enum EitherOrNeither<L, R> {
68 Neither,
69 Left(L),
70 Right(R),
71}
72
73/// An enum that represents either a left (`Left(L)`) or right (`Right(R)`) or both (`Both(L, R)`).
74#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
75pub enum EitherOrBoth<L, R> {
76 Left(L),
77 Right(R),
78 Both(L, R),
79}
80
81/// An enum that represents a single `Neither` value or a pair of values (`Both(L, R)`).
82#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
83pub enum NeitherOrBoth<L, R> {
84 Neither,
85 Both(L, R),
86}
87
88/// An enum that represents either an empty value, left value, right value, or both values.
89#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
90pub enum Quither<L, R> {
91 Neither,
92 Left(L),
93 Right(R),
94 Both(L, R),
95}
96
97impl<T> Either<T, T> {
98 pub fn into_inner(self) -> T {
99 match self {
100 Either::Left(l) => l,
101 Either::Right(r) => r,
102 }
103 }
104}