what_i_want/
lib.rs

1//! Some tools to help with the return value
2//!
3//! # Examples
4//!
5//! ```ignore
6//! use what_i_want::*;
7//!
8//! fn login(username: String) -> bool {
9//!     require!(username == "admin", false);
10//!     ...
11//! }
12//!
13//! fn login2(username: String) {
14//!     require!(username == "admin");
15//!     ...
16//! }
17//!
18//! ```
19//!
20//! # Handling Result and Option
21//!
22//! # Examples
23//!
24//! ```ignore
25//! // Before using `what_i_want`
26//! pub async fn get_mutipart_data(mut mutipart_data: Multipart) -> MultipartData {
27//!     // Nested hell, and different Enum (Result, Option) handling
28//!     // Of course this code is just for demonstration
29//!     while let Some(Ok(mut field)) = mutipart_data.next().await {
30//!         if let Some(disposition) = field.headers().get(&header::CONTENT_DISPOSITION) {
31//!             if let Ok(disposition_str) = disposition.to_str() {
32//!                 if let Some(dis) = ContentDisposition::parse(disposition_str) {
33//!                     if let Some(key) = dis.name {
34//!                         while let Some(Ok(chunk)) = field.next().await {
35//!                             ...
36//!                         }
37//!                     }
38//!                 }
39//!             }
40//!         }
41//!     }
42//!     MultipartData { ... }
43//! }
44//!
45//! // After using `what_i_want`
46//! use what_i_want::*;
47//!
48//! async fn get_mutipart_data(mut mutipart_data: Multipart) -> MultipartData {
49//!     while let Some(Ok(mut field)) = mutipart_data.next().await {
50//!         let disposition = unwrap_or_continue!(field.headers().get(&header::CONTENT_DISPOSITION));
51//!         let disposition_str = unwrap_or_continue!(disposition.to_str());
52//!         let dis = unwrap_or_continue!(ContentDisposition::parse(disposition_str));
53//!         let key = unwrap_or_continue!(dis.name);
54//!         while let Some(Ok(chunk)) = field.next().await {
55//!             ...
56//!         }
57//!     }
58//!     MultipartData { ... }
59//! }
60//! ```
61
62/// Implement `WhatIwant` and let us know what you want
63///
64///
65/// # Examples
66///
67/// ```ignore
68/// use what_i_want::WhatIwant;
69///
70///
71/// impl<T, E> WhatIwant for Result<T, E> {
72///     fn is_i_want(&self) -> bool {
73///         self.is_ok()
74///     }
75/// }
76///
77///
78/// impl<T> WhatIwant for Option<T> {
79///     fn is_i_want(&self) -> bool {
80///         self.is_some()
81///     }
82/// }
83/// 
84/// // Custom enum
85/// enum LoginReply {
86///     Success,
87///     Failed(i32)
88/// }
89///
90/// impl WhatIwant for LoginReply {
91///     fn is_i_want(&self) -> bool {
92///         match self {
93///             LoginReply::Success => true,
94///             _ => false
95///         }
96///     }
97/// }
98///
99/// ```
100pub trait WhatIwant {
101    fn is_i_want(&self) -> bool;
102}
103
104impl<T, E> WhatIwant for Result<T, E> {
105    fn is_i_want(&self) -> bool {
106        self.is_ok()
107    }
108}
109
110impl<T> WhatIwant for Option<T> {
111    fn is_i_want(&self) -> bool {
112        self.is_some()
113    }
114}
115
116#[macro_export]
117/// If it's not what you want, then do what you want
118///
119/// # Examples
120///
121/// ```
122/// use what_i_want::*;
123///
124/// let an_err: Result<Option<i32>, ()> = Ok(Some(1));
125/// let an_option: Option<Option<i32>> = Some(Some(1));
126///
127/// unwrap_or_do!(an_err, Some(0));
128/// unwrap_or_do!(an_option, Some(0));
129///
130/// fn a_func() -> bool {
131///     let an_option = Some(true);
132///     unwrap_or_do!(an_option, return false)
133/// }
134///
135/// ```
136macro_rules! unwrap_or_do {
137    ($exp: expr, $do: expr) => {
138        if $exp.is_i_want() {
139            $do
140        } else {
141            $exp.unwrap()
142        }
143    };
144}
145
146#[macro_export]
147/// If it's not what you want, then do `continue`
148///
149/// # Examples
150///
151/// ```ignore
152/// use what_i_want::*;
153///
154/// async fn get_mutipart_data(mut mutipart_data: Multipart) -> MultipartData {
155///     while let Some(Ok(mut field)) = mutipart_data.next().await {
156///         let disposition = unwrap_or_continue!(field.headers().get(&header::CONTENT_DISPOSITION));
157///         let disposition_str = unwrap_or_continue!(disposition.to_str());
158///         let dis = unwrap_or_continue!(ContentDisposition::parse(disposition_str));
159///         let key = unwrap_or_continue!(dis.name);
160///         while let Some(Ok(chunk)) = field.next().await {
161///             ...
162///         }
163///     }
164///     MultipartData { ... }
165/// }
166/// ```
167macro_rules! unwrap_or_continue {
168    ($exp: expr) => {
169        unwrap_or_do!($exp, continue)
170    };
171}
172
173#[macro_export]
174/// If it's not what you want, then do `return ()`
175///
176/// # Examples
177///
178/// ```ignore
179/// use what_i_want::*;
180///
181/// fn a_func(result: Result<i32, ()>) -> () {
182///     let unwrapped = unwrap_or_return!(result);
183///     // If ok, do something, else return
184///     ...
185/// }
186/// ```
187macro_rules! unwrap_or_return {
188    ($exp: expr) => {
189        unwrap_or_do!($exp, return)
190    };
191}
192
193#[macro_export]
194/// If it's not what you want, then do `return false`
195///
196/// # Examples
197///
198/// ```ignore
199/// use what_i_want::*;
200///
201/// fn a_func(result: Result<i32, ()>) -> bool {
202///     let unwrapped = unwrap_or_false!(result);
203///     // If ok, do something, else return
204///     ...
205/// }
206/// ```
207macro_rules! unwrap_or_false {
208    ($exp: expr) => {
209        unwrap_or_do!($exp, return false)
210    };
211}
212
213#[macro_export]
214/// If it's not what you want, then do `return true`
215///
216/// # Examples
217///
218/// ```ignore
219/// use what_i_want::*;
220///
221/// fn a_func(result: Result<i32, ()>) -> bool {
222///     let unwrapped = unwrap_or_true!(result);
223///     // If ok, do something, else return
224///     ...
225/// }
226/// ```
227macro_rules! unwrap_or_true {
228    ($exp: expr) => {
229        unwrap_or_do!($exp, return true)
230    };
231}
232
233#[macro_export]
234/// If it's not what you want, then do `return <defined return value>`
235///
236/// # Examples
237///
238/// ```ignore
239/// use what_i_want::*;
240///
241/// fn a_func(result: Result<i32, ()>) -> bool {
242///     let unwrapped = unwrap_or_val!(result, false);
243///     // If ok, do something, else return
244///     ...
245/// }
246/// ```
247macro_rules! unwrap_or_val {
248    ($exp: expr, $val: expr) => {
249        unwrap_or_do!($exp, return $val)
250    };
251}
252
253#[macro_export]
254/// Execute if the condition is true, otherwise return
255///
256/// # Examples
257///
258/// ```ignore
259/// use what_i_want::*;
260///
261/// fn login(username: String) -> bool {
262///     require!(username == "admin", false);
263/// }
264///
265/// fn login2(username: String) {
266///     require!(username == "admin");
267/// }
268/// ```
269macro_rules! require {
270    ($condition: expr) => {
271        if !$condition {
272            return;
273        }
274    };
275    ($condition: expr, $return: expr) => {
276        if !$condition {
277            return $return;
278        }
279    };
280}