stry_common/utils/fenn/
mod.rs

1//! This module contains part of my general util library `fenn`, and is used as a 'testing' environment.
2
3#![deny(unsafe_code)]
4
5mod capture;
6mod hash;
7pub mod iter;
8mod newtype;
9mod peep;
10pub mod slice;
11mod string;
12mod vec;
13pub mod vec_map;
14mod wrap;
15
16pub use self::{
17    hash::HashMapExt,
18    peep::{PeekOption, Peep, PeepResult},
19    string::StringExt,
20    vec::VecExt,
21    wrap::Wrap,
22};
23
24/// A [`try!`] like macro for `Result<Option<_>, _>`s.
25///
26/// [`try!`]: https://doc.rust-lang.org/std/macro.try.html
27#[macro_export]
28macro_rules! try_res_opt {
29    ($inner:expr) => {
30        match $inner {
31            ::core::result::Result::Ok(::core::option::Option::Some(value)) => {
32                ::core::result::Result::Ok(value)
33            }
34            ::core::result::Result::Ok(::core::option::Option::None) => {
35                return ::core::result::Result::Ok(::core::option::Option::None)
36            }
37            ::core::result::Result::Err(err) => return ::core::result::Result::Err(err),
38        }
39    };
40    ($inner:expr,) => {
41        $crate::try_res_opt!($inner)
42    };
43}
44
45/// Various extensions to the bool primitive.
46pub trait BoolExt: Copy {
47    /// A stable version of [`then_some`](https://doc.rust-lang.org/std/primitive.bool.html#method.then_some).
48    ///
49    /// Returns `Some(t)` if the `bool` is `true`, or `None` otherwise.
50    ///
51    /// # Examples
52    ///
53    /// ```rust
54    /// use fenn::BoolExt;
55    ///
56    /// assert_eq!(false.some(0), None);
57    /// assert_eq!(true.some(0), Some(0));
58    /// ```
59    fn some<T>(self, t: T) -> Option<T>;
60
61    /// A stable version of [`then`](https://doc.rust-lang.org/std/primitive.bool.html#method.then).
62    ///
63    /// Returns `Some(f())` if the `bool` is `true`, or `None` otherwise.
64    ///
65    /// # Examples
66    ///
67    /// ```rust
68    /// use fenn::BoolExt;
69    ///
70    /// assert_eq!(false.some_with(|| 0), None);
71    /// assert_eq!(true.some_with(|| 0), Some(0));
72    /// ```
73    fn some_with<T, F>(self, run: F) -> Option<T>
74    where
75        F: FnOnce() -> T;
76
77    /// Returns `Some(())` if the `bool` is `true`, or `None` otherwise.
78    ///
79    /// # Examples
80    ///
81    /// ```rust
82    /// use fenn::BoolExt;
83    ///
84    /// assert!(false.as_option().is_none());
85    /// assert!(true.as_option().is_some());
86    /// ```
87    fn as_option(self) -> Option<()>;
88
89    /// Returns `Ok(t)` if the `bool` is `true`, or `Er(())` otherwise.
90    ///
91    /// # Examples
92    ///
93    /// ```rust
94    /// use fenn::BoolExt;
95    ///
96    /// assert_eq!(false.ok(0), Err(()));
97    /// assert_eq!(true.ok(0), Ok(0));
98    /// ```
99    fn ok<T>(self, t: T) -> Result<T, ()>;
100
101    /// Returns `Ok(run())` if the `bool` is `true`, or `Er(())` otherwise.
102    ///
103    /// # Examples
104    ///
105    /// ```rust
106    /// use fenn::BoolExt;
107    ///
108    /// assert_eq!(false.ok_with(|| 0), Err(()));
109    /// assert_eq!(true.ok_with(|| 0), Ok(0));
110    /// ```
111
112    fn ok_with<T, F>(self, run: F) -> Result<T, ()>
113    where
114        F: FnOnce() -> T;
115
116    /// Returns `Ok(())` if the `bool` is `true`, or `Err(())` otherwise.
117    fn as_result(self) -> Result<(), ()>;
118}
119
120impl BoolExt for bool {
121    fn some<T>(self, t: T) -> Option<T> {
122        if self {
123            Some(t)
124        } else {
125            None
126        }
127    }
128
129    fn some_with<T, F>(self, run: F) -> Option<T>
130    where
131        F: FnOnce() -> T,
132    {
133        self.some(run())
134    }
135
136    fn as_option(self) -> Option<()> {
137        self.some(())
138    }
139
140    fn ok<T>(self, t: T) -> Result<T, ()> {
141        if self {
142            Ok(t)
143        } else {
144            Err(())
145        }
146    }
147
148    fn ok_with<T, F>(self, run: F) -> Result<T, ()>
149    where
150        F: FnOnce() -> T,
151    {
152        self.ok(run())
153    }
154
155    fn as_result(self) -> Result<(), ()> {
156        self.ok(())
157    }
158}
159
160/// Wrap `Self` in a [`Option`] based off a predicate.
161///
162/// [`Option`]: https://doc.rust-lang.org/std/option/enum.Option.html
163pub trait IntoOption
164where
165    Self: Sized,
166{
167    /// Results `Some(self)` if the predicate returns `true`, or `None` otherwise.
168    fn some_if(self, predicate: bool) -> Option<Self> {
169        if predicate {
170            Some(self)
171        } else {
172            None
173        }
174    }
175
176    /// Results `Some(self)` if the predicate returns `true`, or `None` otherwise.
177    fn with_some_if<F>(self, predicate: F) -> Option<Self>
178    where
179        F: FnOnce(&Self) -> bool,
180    {
181        let res = predicate(&self);
182
183        self.some_if(res)
184    }
185
186    /// Results `None` if the predicate returns `true`, or `Some(self)` otherwise.
187    fn none_if(self, predicate: bool) -> Option<Self> {
188        if predicate {
189            None
190        } else {
191            Some(self)
192        }
193    }
194
195    /// Results `None` if the predicate returns `true`, or `Some(self)` otherwise.
196    fn with_none_if<F>(self, predicate: F) -> Option<Self>
197    where
198        F: FnOnce(&Self) -> bool,
199    {
200        let res = predicate(&self);
201
202        self.none_if(res)
203    }
204}
205
206impl<T> IntoOption for T {}
207
208/// Wrap `Self` in a [`Result`] based off a predicate.
209///
210/// [`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html
211pub trait IntoResult
212where
213    Self: Sized,
214{
215    /// Results `Ok(self)` if the predicate returns `true`, or `Err(err)` otherwise.
216    fn ok_if<E>(self, predicate: bool, err: E) -> Result<Self, E> {
217        if predicate {
218            Ok(self)
219        } else {
220            Err(err)
221        }
222    }
223
224    /// Results `Ok(self)` if the predicate returns `true`, or `Err(err)` otherwise.
225    fn with_ok_if<F, E>(self, predicate: F, err: E) -> Result<Self, E>
226    where
227        F: FnOnce(&Self) -> bool,
228    {
229        let res = predicate(&self);
230
231        self.ok_if(res, err)
232    }
233
234    /// Results `Err(err)` if the predicate returns `true`, or `Ok(self)` otherwise.
235    fn err_if<E>(self, predicate: bool, err: E) -> Result<Self, E> {
236        if predicate {
237            Err(err)
238        } else {
239            Ok(self)
240        }
241    }
242
243    /// Results `Err(err)` if the predicate returns `true`, or `Ok(self)` otherwise.
244    fn with_err_if<F, E>(self, predicate: F, err: E) -> Result<Self, E>
245    where
246        F: FnOnce(&Self) -> bool,
247    {
248        let res = predicate(&self);
249
250        self.err_if(res, err)
251    }
252}
253
254impl<T> IntoResult for T {}
255
256/// Various extensions to
257/// [`Option`](https://doc.rust-lang.org/std/option/enum.Option.html).
258pub trait OptionExt {
259    /// The item type inside the `Option`.
260    type Item;
261
262    /// Take the value of `self` only if the given condition is `true`.
263    fn take_if<F>(&mut self, fun: F) -> Option<Self::Item>
264    where
265        F: FnOnce(&Self::Item) -> bool;
266}
267
268impl<T> OptionExt for Option<T> {
269    type Item = T;
270
271    fn take_if<F>(&mut self, fun: F) -> Option<Self::Item>
272    where
273        F: FnOnce(&Self::Item) -> bool,
274    {
275        if self.as_ref().map(fun).unwrap_or(false) {
276            self.take()
277        } else {
278            None
279        }
280    }
281}
282
283#[doc(hidden)]
284pub mod lib {
285    pub use std::boxed::Box;
286    pub use std::collections::HashMap;
287    pub use std::fmt;
288    pub use std::string::String;
289    pub use std::sync::Arc;
290    pub use std::vec;
291}