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::*;