ferroui_dynamic_data/kernel/
option_extensions.rs1use super::OptionElse;
10use std::collections::HashMap;
11use std::hash::Hash;
12
13pub trait OptionExtensions<T>: Sized {
15 fn convert<U>(self, converter: impl FnOnce(T) -> U) -> Option<U>;
17
18 fn convert_optional<U>(self, converter: impl FnOnce(T) -> Option<U>) -> Option<U>;
21
22 fn convert_or<U>(self, converter: impl FnOnce(T) -> U, fallback_converter: impl FnOnce() -> U) -> U;
25
26 fn if_has_value(self, action: impl FnOnce(T)) -> OptionElse;
29
30 fn value_or(self, value_selector: impl FnOnce() -> T) -> T;
32
33 fn value_or_default(self) -> T
35 where
36 T: Default;
37
38 fn value_or_throw<E>(self, exception_generator: impl FnOnce() -> E) -> Result<T, E>;
44}
45
46impl<T> OptionExtensions<T> for Option<T> {
47 fn convert<U>(self, converter: impl FnOnce(T) -> U) -> Option<U> {
48 self.map(converter)
49 }
50
51 fn convert_optional<U>(self, converter: impl FnOnce(T) -> Option<U>) -> Option<U> {
52 self.and_then(converter)
53 }
54
55 fn convert_or<U>(self, converter: impl FnOnce(T) -> U, fallback_converter: impl FnOnce() -> U) -> U {
56 match self {
57 Some(value) => converter(value),
58 None => fallback_converter(),
59 }
60 }
61
62 fn if_has_value(self, action: impl FnOnce(T)) -> OptionElse {
63 match self {
64 Some(value) => {
65 action(value);
66 OptionElse::no_action()
67 }
68 None => OptionElse::run(),
69 }
70 }
71
72 fn value_or(self, value_selector: impl FnOnce() -> T) -> T {
73 self.unwrap_or_else(value_selector)
74 }
75
76 fn value_or_default(self) -> T
77 where
78 T: Default,
79 {
80 self.unwrap_or_default()
81 }
82
83 fn value_or_throw<E>(self, exception_generator: impl FnOnce() -> E) -> Result<T, E> {
84 self.ok_or_else(exception_generator)
85 }
86}
87
88pub fn first_or_optional<T>(source: impl IntoIterator<Item = T>, selector: impl Fn(&T) -> bool) -> Option<T> {
90 source.into_iter().find(|item| selector(item))
91}
92
93pub fn lookup<K: Eq + Hash, V: Clone>(source: &HashMap<K, V>, key: &K) -> Option<V> {
95 source.get(key).cloned()
96}
97
98pub fn remove_if_contained<K: Eq + Hash, V>(source: &mut HashMap<K, V>, key: &K) -> bool {
100 source.remove(key).is_some()
101}
102
103pub fn select_values<T>(source: impl IntoIterator<Item = Option<T>>) -> Vec<T> {
105 source.into_iter().flatten().collect()
106}