deep_flatten/
lib.rs

1#![doc = include_str!("../README.md")]
2
3/// Trait for deep flattening Options.
4pub trait OptionDeepFlatten<T> {
5    /// Convert nested Options e.g. `Option<Option<Option<T>>>` into Option<T>.
6    /// Can convert up to 32 Options.
7    fn deep_flatten(self) -> Option<T>;
8}
9
10macro_rules! __impl_option {
11    ($_ignored:ident) => {};
12    ($_ignored:ident $($t:ident)+) => {
13        impl<T> OptionDeepFlatten<T> for __impl_option!(@nest_option $($t)+) {
14            fn deep_flatten(self) -> Option<T> {
15                match self {
16                    __impl_option!(@nest_some(inner) $($t)+) => Some(inner),
17                    _ => None,
18                }
19            }
20        }
21        __impl_option!($($t)*);
22    };
23
24    (@nest_option $_ignored:ident) => { Option<T> };
25    (@nest_option $_ignored:ident $($t:ident)+) => {
26        Option<__impl_option!(@nest_option $($t)+)>
27    };
28    (@nest_some($dst:ident) $($_ignored:ident)?) => { Some($dst) };
29    (@nest_some($dst:ident) $_ignored:ident $($t:ident)+) => {
30        Some(__impl_option!(@nest_some($dst) $($t)+))
31    };
32}
33
34// Impl for up to 32 Options.
35__impl_option!(IGNORED
36    Option 
37    Option 
38    Option 
39    Option 
40    Option 
41    Option 
42    Option 
43    Option 
44    Option 
45    Option 
46    Option 
47    Option 
48    Option 
49    Option 
50    Option 
51    Option 
52    Option 
53    Option 
54    Option 
55    Option 
56    Option 
57    Option 
58    Option 
59    Option 
60    Option 
61    Option 
62    Option 
63    Option 
64    Option 
65    Option 
66    Option 
67    Option
68);