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}