rust_overture/
options.rs

1/// Free `map` on Option for function composition.
2pub fn map<A, B>(transform: impl Fn(A) -> B + Clone + 'static) -> impl Fn(Option<A>) -> Option<B> {
3    move |opt| opt.map(transform.clone())
4}
5
6/// Free `map` on Option for function composition with fallible transform.
7pub fn map_try<A, B, E>(
8    transform: impl Fn(A) -> Result<B, E> + Clone + 'static,
9) -> impl Fn(Option<A>) -> Result<Option<B>, E> {
10    move |opt| match opt {
11        Some(a) => transform.clone()(a).map(Some),
12        None => Ok(None),
13    }
14}
15
16/// Transforms a pair of options into an option pair.
17pub fn zip<A, B>(opt1: Option<A>, opt2: Option<B>) -> Option<(A, B)> {
18    match (opt1, opt2) {
19        (Some(a), Some(b)) => Some((a, b)),
20        _ => None,
21    }
22}
23
24/// Transforms a pair of options into a new optional value using a transform function.
25pub fn zip_with<A, B, Z>(
26    transform: impl Fn(A, B) -> Z + Clone + 'static,
27    opt1: Option<A>,
28    opt2: Option<B>,
29) -> Option<Z> {
30    zip(opt1, opt2).map(|(a, b)| transform(a, b))
31}
32
33#[macro_export]
34macro_rules! map_macro {
35    ($f:expr) => {
36        rust_overture::options::map($f)
37    };
38}
39
40#[macro_export]
41macro_rules! map_try_macro {
42    ($f:expr) => {
43        rust_overture::options::map_try($f)
44    };
45}
46
47#[macro_export]
48macro_rules! zip_macro {
49    ($a:expr, $b:expr) => {
50        rust_overture::options::zip($a, $b)
51    };
52}
53
54#[macro_export]
55macro_rules! zip_with_macro {
56    ($f:expr, $a:expr, $b:expr) => {
57        rust_overture::options::zip_with($f, $a, $b)
58    };
59}