1#![doc = include_str!("../README.md")]
2
3#[macro_export]
13macro_rules! some_or_return {
14 ($from:expr) => {{
15 if let Some(f) = $from {
16 f
17 } else {
18 return;
19 }
20 }};
21 ($from:expr, $default_result:expr) => {{
22 if let Some(f) = $from {
23 f
24 } else {
25 return $default_result;
26 }
27 }};
28}
29
30#[macro_export]
49macro_rules! some_or_break {
50 ($from:expr) => {{
51 if let Some(f) = $from {
52 f
53 } else {
54 break;
55 }
56 }};
57
58 ($from:expr, $lt:lifetime) => {{
59 if let Some(f) = $from {
60 f
61 } else {
62 break $lt;
63 }
64 }};
65}
66
67#[macro_export]
86macro_rules! some_or_continue {
87 ($from:expr) => {{
88 if let Some(f) = $from {
89 f
90 } else {
91 continue;
92 }
93 }};
94
95 ($from:expr, $lt:lifetime) => {{
96 if let Some(f) = $from {
97 f
98 } else {
99 continue $lt;
100 }
101 }};
102}
103
104#[macro_export]
113macro_rules! ok_or_return {
114 ($from:expr) => {{
115 if let Ok(f) = $from {
116 f
117 } else {
118 return;
119 }
120 }};
121
122 ($from:expr, $default_result:expr) => {{
123 if let Ok(f) = $from {
124 f
125 } else {
126 return $default_result;
127 }
128 }};
129}
130
131#[macro_export]
150macro_rules! ok_or_break {
151 ($from:expr) => {{
152 if let Ok(f) = $from {
153 f
154 } else {
155 break;
156 }
157 }};
158 ($from:expr, $lt:lifetime) => {{
159 if let Ok(f) = $from {
160 f
161 } else {
162 break $lt;
163 }
164 }};
165}
166
167#[macro_export]
186macro_rules! ok_or_continue {
187 ($from:expr) => {{
188 if let Ok(f) = $from {
189 f
190 } else {
191 continue;
192 }
193 }};
194 ($from:expr, $lt:lifetime) => {{
195 if let Ok(f) = $from {
196 f
197 } else {
198 continue $lt;
199 }
200 }};
201}
202
203#[cfg(test)]
204mod test {
205 struct Tester {
206 value: i32,
207 }
208
209 impl Tester {
210 fn new() -> Tester {
211 Tester { value: 0 }
212 }
213
214 fn increment_with_optional(&mut self, value: Option<i32>) {
215 let value = some_or_return!(value);
216 self.value += value;
217 }
218
219 fn increment_with_result(&mut self, value: Result<i32, ()>) {
220 let value = ok_or_return!(value);
221 self.value += value;
222 }
223
224 fn increment_with_optional_with_ref(&mut self, value: Option<&i32>) {
225 let value = some_or_return!(value);
226 self.value += value;
227 }
228
229 fn increment_with_result_with_ref(&mut self, value: Result<&i32, ()>) {
230 let value = ok_or_return!(value);
231 self.value += value;
232 }
233
234 fn increment_with_ref_to_optional(&mut self, value: &Option<i32>) {
235 let value = some_or_return!(value);
236 self.value += value;
237 }
238
239 fn increment_with_ref_to_result(&mut self, value: &Result<i32, ()>) {
240 let value = ok_or_return!(value);
241 self.value += value;
242 }
243
244 fn increment_with_optional_with_break(&mut self, values: Vec<Option<i32>>) {
245 for value in values {
246 let value = some_or_break!(value);
247 self.value += value;
248 }
249 }
250
251 fn increment_with_optional_with_break_with_lifetime(&mut self, values: Vec<Option<i32>>) {
252 'l: for value in values {
253 self.value += 1;
254 for _i in 0..1 {
255 let value = some_or_break!(value, 'l);
256 self.value += value;
257 }
258 }
259 }
260
261 fn increment_with_optional_with_continue(&mut self, values: Vec<Option<i32>>) {
262 for value in values {
263 let value = some_or_continue!(value);
264 self.value += value;
265 }
266 }
267
268 fn increment_with_optional_with_continue_with_lifetime(
269 &mut self,
270 values: Vec<Option<i32>>,
271 ) {
272 'l: for value in values {
273 self.value += 1;
274 for _i in 0..1 {
275 let value = some_or_continue!(value, 'l);
276 self.value += value;
277 }
278 }
279 }
280
281 fn increment_with_result_with_break(&mut self, values: Vec<Result<i32, ()>>) {
282 for value in values {
283 let value = ok_or_break!(value);
284 self.value += value;
285 }
286 }
287
288 fn increment_with_result_with_break_with_lifetime(&mut self, values: Vec<Result<i32, ()>>) {
289 'l: for value in values {
290 self.value += 1;
291 for _i in 0..1 {
292 let value = ok_or_break!(value, 'l);
293 self.value += value;
294 }
295 }
296 }
297
298 fn increment_with_result_with_continue(&mut self, values: Vec<Result<i32, ()>>) {
299 for value in values {
300 let value = ok_or_continue!(value);
301 self.value += value;
302 }
303 }
304
305 fn increment_with_result_with_continue_with_lifetime(
306 &mut self,
307 values: Vec<Result<i32, ()>>,
308 ) {
309 'l: for value in values {
310 self.value += 1;
311 for _i in 0..1 {
312 let value = ok_or_continue!(value, 'l);
313 self.value += value;
314 }
315 }
316 }
317
318 fn increment_with_optional_by_ref(
319 &mut self,
320 values: Option<i32>
321 ) {
322
323 let i: &i32 = some_or_return!(values.as_ref());
324 self.value += i;
325 }
326
327 fn increment_with_optional_from_fn_result<F: Fn() -> Option<i32>>(
328 &mut self,
329 value_getter: F
330 ) {
331
332 let i: i32 = some_or_return!(value_getter());
333 self.value += i;
334 }
335 }
336
337 #[test]
338 fn should_return_early_with_unengaged_optional() {
339 let mut tester = Tester::new();
340 tester.increment_with_optional(None);
341 assert_eq!(tester.value, 0);
342 }
343
344 #[test]
345 fn should_not_return_early_with_engaged_optional() {
346 let mut tester = Tester::new();
347 tester.increment_with_optional(Some(1));
348 assert_eq!(tester.value, 1);
349 }
350
351 #[test]
352 fn should_return_early_with_err() {
353 let mut tester = Tester::new();
354 tester.increment_with_result(Err(()));
355 assert_eq!(tester.value, 0);
356 }
357
358 #[test]
359 fn should_not_return_early_with_ok() {
360 let mut tester = Tester::new();
361 tester.increment_with_result(Ok(1));
362 assert_eq!(tester.value, 1);
363 }
364
365 #[test]
366 fn should_return_early_with_unengaged_optional_with_ref() {
367 let mut tester = Tester::new();
368 tester.increment_with_optional_with_ref(None);
369 assert_eq!(tester.value, 0);
370 }
371
372 #[test]
373 fn should_not_return_early_with_engaged_optional_with_ref() {
374 let mut tester = Tester::new();
375 tester.increment_with_optional_with_ref(Some(&1));
376 assert_eq!(tester.value, 1);
377 }
378
379 #[test]
380 fn should_return_early_with_err_with_ref() {
381 let mut tester = Tester::new();
382 tester.increment_with_result_with_ref(Err(()));
383 assert_eq!(tester.value, 0);
384 }
385
386 #[test]
387 fn should_not_return_early_with_ok_with_ref() {
388 let mut tester = Tester::new();
389 tester.increment_with_result_with_ref(Ok(&1));
390 assert_eq!(tester.value, 1);
391 }
392
393 #[test]
394 fn should_return_early_with_ref_to_unengaged_optional() {
395 let mut tester = Tester::new();
396 tester.increment_with_ref_to_optional(&None);
397 assert_eq!(tester.value, 0);
398 }
399
400 #[test]
401 fn should_not_return_early_with_ref_to_engaged_optional() {
402 let mut tester = Tester::new();
403 tester.increment_with_ref_to_optional(&Some(1));
404 assert_eq!(tester.value, 1);
405 }
406
407 #[test]
408 fn should_return_early_with_ref_to_err() {
409 let mut tester = Tester::new();
410 tester.increment_with_ref_to_result(&Err(()));
411 assert_eq!(tester.value, 0);
412 }
413
414 #[test]
415 fn should_not_return_early_with_ref_to_ok() {
416 let mut tester = Tester::new();
417 tester.increment_with_ref_to_result(&Ok(1));
418 assert_eq!(tester.value, 1);
419 }
420
421 #[test]
422 fn should_break_with_unengaged_optional() {
423 let mut tester = Tester::new();
424 tester.increment_with_optional_with_break(vec![None, Some(1)]);
425 assert_eq!(tester.value, 0);
426 }
427
428 #[test]
429 fn should_break_with_unengaged_optional_with_lifetime() {
430 let mut tester = Tester::new();
431 tester.increment_with_optional_with_break_with_lifetime(vec![None, Some(1)]);
432 assert_eq!(tester.value, 1);
433 }
434
435 #[test]
436 fn should_continue_with_unengaged_optional() {
437 let mut tester = Tester::new();
438 tester.increment_with_optional_with_continue(vec![None, Some(1)]);
439 assert_eq!(tester.value, 1);
440 }
441
442 #[test]
443 fn should_continue_with_unengaged_optional_with_lifetime() {
444 let mut tester = Tester::new();
445 tester.increment_with_optional_with_continue_with_lifetime(vec![None, Some(1)]);
446 assert_eq!(tester.value, 3);
447 }
448
449 #[test]
450 fn should_break_with_err_result() {
451 let mut tester = Tester::new();
452 tester.increment_with_result_with_break(vec![Err(()), Ok(1)]);
453 assert_eq!(tester.value, 0);
454 }
455
456 #[test]
457 fn should_break_with_err_result_with_lifetime() {
458 let mut tester = Tester::new();
459 tester.increment_with_result_with_break_with_lifetime(vec![Err(()), Ok(1)]);
460 assert_eq!(tester.value, 1);
461 }
462
463 #[test]
464 fn should_continue_with_err_result() {
465 let mut tester = Tester::new();
466 tester.increment_with_result_with_continue(vec![Err(()), Ok(1)]);
467 assert_eq!(tester.value, 1);
468 }
469
470 #[test]
471 fn should_continue_with_err_result_with_lifetime() {
472 let mut tester = Tester::new();
473 tester.increment_with_result_with_continue_with_lifetime(vec![Err(()), Ok(1)]);
474 assert_eq!(tester.value, 3);
475 }
476
477 #[test]
478 fn should_get_optional_from_reference() {
479 let mut tester = Tester::new();
480 tester.increment_with_optional_by_ref(Some(1));
481 assert_eq!(tester.value, 1);
482 tester.increment_with_optional_by_ref(None);
483 assert_eq!(tester.value, 1);
484 }
485
486 #[test]
487 fn should_get_optional_from_function_result() {
488 let mut tester = Tester::new();
489 tester.increment_with_optional_from_fn_result(|| Some(1));
490 assert_eq!(tester.value, 1);
491 tester.increment_with_optional_from_fn_result(|| None);
492 assert_eq!(tester.value, 1);
493 let a = 1;
494 tester.increment_with_optional_from_fn_result(|| Some(a));
495 assert_eq!(tester.value, 2);
496 }
497
498 #[derive(Debug, Eq, PartialEq)]
499 struct MeaningOfLifeAnd {
500 value: i32
501 }
502
503 fn try_some_or_return_with_default(val: Option<i32>) -> MeaningOfLifeAnd {
504 let val = some_or_return!(val, MeaningOfLifeAnd { value: 42 });
505 MeaningOfLifeAnd {
506 value: val + 42
507 }
508 }
509
510 #[test]
511 fn should_return_default_when_none() {
512 assert_eq!(try_some_or_return_with_default(Some(1)), MeaningOfLifeAnd { value: 43 });
513 assert_eq!(try_some_or_return_with_default(None), MeaningOfLifeAnd { value: 42 });
514 }
515
516 fn try_ok_or_return_with_default(val: Result<i32, ()>) -> MeaningOfLifeAnd {
517 let val = ok_or_return!(val, MeaningOfLifeAnd { value: 42 });
518 MeaningOfLifeAnd {
519 value: val + 42
520 }
521 }
522
523 #[test]
524 fn should_return_default_when_err() {
525 assert_eq!(try_ok_or_return_with_default(Ok(1)), MeaningOfLifeAnd { value: 43 });
526 assert_eq!(try_ok_or_return_with_default(Err(())), MeaningOfLifeAnd { value: 42 });
527 }
528}