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}