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 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
//! `option-operations` provides traits and auto-implementations to
//! improve arithmetic operations usability when dealing with `Option`s.
//!
//! # Example
//!
//! Dealing with two `Option`s, can lead to verbose expressions:
//!
//! ```
//! let lhs = Some(1u64);
//! let rhs = Some(u64::MAX);
//!
//! assert_eq!(
//! lhs.zip(rhs).map(|(lhs, rhs)| lhs.saturating_add(rhs)),
//! Some(u64::MAX),
//! );
//! ```
//!
//! Thanks to the trait [`OptionSaturatingAdd`] we can write:
//!
//! ```
//! # use option_operations::{Error, OptionSaturatingAdd};
//! # let lhs = Some(1u64);
//! # let rhs = Some(u64::MAX);
//! assert_eq!(
//! lhs.opt_saturating_add(rhs),
//! Some(u64::MAX),
//! );
//! ```
//!
//! The trait can also be used with the inner type:
//!
//! ```
//! # use option_operations::{Error, OptionSaturatingAdd};
//! # let lhs = Some(1u64);
//! # let rhs = Some(u64::MAX);
//! assert_eq!(
//! lhs.opt_saturating_add(u64::MAX),
//! Some(u64::MAX),
//! );
//!
//! assert_eq!(
//! 1.opt_saturating_add(rhs),
//! Some(u64::MAX),
//! );
//! ```
//!
//! # Alternative to `PartialOrd` for `Option<T>`
//!
//! Another purpose is to workaround the `PartiaOrd` implementation
//! for `Option<T>`, which uses the declaration order of the variants
//! for `Option`. `None` appearing before `Some(_)`, it results in
//! the following behavior:
//!
//! ```
//! # use core::cmp::Ordering;
//! let some_0 = Some(0);
//! let none: Option<u64> = None;
//!
//! assert_eq!(none.partial_cmp(&some_0), Some(Ordering::Less));
//! assert_eq!(some_0.partial_cmp(&none), Some(Ordering::Greater));
//! ```
//!
//! In some cases, we might consider that `None` reflects a value which
//! is not defined and thus can not be compared with `Some(_)`.
//!
//! ```
//! # use option_operations::{OptionOperations, OptionOrd};
//! # let some_0 = Some(0);
//! # let none: Option<u64> = None;
//! assert_eq!(none.opt_cmp(&some_0), None);
//! assert_eq!(some_0.opt_cmp(&none), None);
//! ```
//!
//! Of course, this is consistent with other usual comparisons:
//!
//! ``` rust
//! # use option_operations::{OptionOperations, OptionOrd, OptionMinMax};
//! # let some_0 = Some(0);
//! # let none: Option<u64> = None;
//! assert_eq!(none.opt_lt(&some_0), None);
//! assert_eq!(none.opt_min(some_0), None);
//! ```
#![forbid(unsafe_code)]
#![cfg_attr(not(feature = "std"), no_std)]
/// Trait for inner types participating in `option-operations`.
///
/// The purpose of this trait is twofold:
///
/// - Auto-implement various `Option*` traits such as `OptionOrd`.
/// - Prevent some conflicting auto-implementation of traits on
/// `Option<T>`.
pub trait OptionOperations {}
impl<T: OptionOperations> OptionOperations for &T {}
impl<T: OptionOperations> OptionOperations for &mut T {}
#[macro_use]
mod macros;
impl_for_all!(OptionOperations);
pub mod add;
pub use add::{
OptionAdd, OptionAddAssign, OptionCheckedAdd, OptionOverflowingAdd, OptionSaturatingAdd,
OptionWrappingAdd,
};
pub mod error;
pub use error::Error;
pub mod div;
pub use div::{
OptionCheckedDiv, OptionDiv, OptionDivAssign, OptionOverflowingDiv, OptionWrappingDiv,
};
pub mod eq;
pub use eq::OptionEq;
pub mod min_max;
pub use min_max::OptionMinMax;
pub mod mul;
pub use mul::{
OptionCheckedMul, OptionMul, OptionMulAssign, OptionOverflowingMul, OptionSaturatingMul,
OptionWrappingMul,
};
pub mod ord;
pub use ord::OptionOrd;
pub mod rem;
pub use rem::{
OptionCheckedRem, OptionOverflowingRem, OptionRem, OptionRemAssign, OptionWrappingRem,
};
pub mod sub;
pub use sub::{
OptionCheckedSub, OptionOverflowingSub, OptionSaturatingSub, OptionSub, OptionSubAssign,
OptionWrappingSub,
};
pub mod prelude {
pub use crate::add::{
OptionAdd, OptionAddAssign, OptionCheckedAdd, OptionOverflowingAdd, OptionSaturatingAdd,
OptionWrappingAdd,
};
pub use crate::div::{
OptionCheckedDiv, OptionDiv, OptionDivAssign, OptionOverflowingDiv, OptionWrappingDiv,
};
pub use crate::eq::OptionEq;
pub use crate::min_max::OptionMinMax;
pub use crate::mul::{
OptionCheckedMul, OptionMul, OptionMulAssign, OptionOverflowingMul, OptionSaturatingMul,
OptionWrappingMul,
};
pub use crate::ord::OptionOrd;
pub use crate::rem::{
OptionCheckedRem, OptionOverflowingRem, OptionRem, OptionRemAssign, OptionWrappingRem,
};
pub use crate::sub::{
OptionCheckedSub, OptionOverflowingSub, OptionSaturatingSub, OptionSub, OptionSubAssign,
OptionWrappingSub,
};
pub use crate::OptionOperations;
}