Skip to main content

functora/
lib.rs

1#![doc = include_str!("../README.md")]
2
3pub use std::ops::ControlFlow;
4
5pub fn id<T>(x: T) -> T {
6    x
7}
8
9pub fn ok<E>() -> Result<(), E> {
10    Ok(())
11}
12
13pub trait Void {
14    fn void(&self);
15}
16
17impl<T> Void for T {
18    fn void(&self) {}
19}
20
21pub fn void<T>(_: T) {}
22
23pub trait Tweak
24where
25    Self: Sized,
26{
27    fn tweak(&mut self, f: impl FnOnce(&Self) -> Self);
28    fn try_tweak<E>(&mut self, f: impl FnOnce(&Self) -> Result<Self, E>) -> Result<(), E>;
29}
30
31impl<T> Tweak for T {
32    fn tweak(&mut self, f: impl FnOnce(&T) -> T) {
33        *self = f(self);
34    }
35    fn try_tweak<E>(&mut self, f: impl FnOnce(&T) -> Result<Self, E>) -> Result<(), E> {
36        f(self).and_then(|x| {
37            *self = x;
38            ok()
39        })
40    }
41}
42
43pub trait Guard<E>
44where
45    Self: Sized,
46{
47    fn guard(self, e: E) -> Result<(), E> {
48        self.guard_then(|| e)
49    }
50    fn guard_then(self, f: impl FnOnce() -> E) -> Result<(), E>;
51}
52
53impl<E> Guard<E> for bool {
54    fn guard_then(self, f: impl FnOnce() -> E) -> Result<(), E> {
55        if self { ok() } else { Err(f()) }
56    }
57}
58
59impl<T, E> Guard<E> for Option<T>
60where
61    T: Guard<E>,
62{
63    fn guard_then(self, f: impl FnOnce() -> E) -> Result<(), E> {
64        match self {
65            None => Err(f()),
66            Some(x) => x.guard_then(f),
67        }
68    }
69}
70
71impl<T, EOuter, EInner> Guard<EOuter> for Result<T, EInner>
72where
73    T: Guard<EOuter>,
74    EOuter: From<EInner>,
75{
76    fn guard_then(self, f: impl FnOnce() -> EOuter) -> Result<(), EOuter> {
77        self?.guard_then(f)
78    }
79}
80
81pub fn guard<T, E>(x: T, e: E) -> Result<(), E>
82where
83    T: Guard<E>,
84{
85    x.guard(e)
86}
87
88pub fn guard_then<T, E>(x: T, f: impl FnOnce() -> E) -> Result<(), E>
89where
90    T: Guard<E>,
91{
92    x.guard_then(f)
93}
94
95pub fn from_control_flow<T>(cf: ControlFlow<T, T>) -> T {
96    match cf {
97        ControlFlow::Continue(x) | ControlFlow::Break(x) => x,
98    }
99}
100
101#[cfg(feature = "futures")]
102mod futures;
103#[cfg(feature = "futures")]
104pub use crate::futures::*;