use std::ops::Add; pub fn combine_options(a: Option, b: Option, f: impl FnOnce(T, T) -> T) -> Option { match (a, b) { (Some(a), Some(b)) => Some(f(a, b)), (Some(v), None) | (None, Some(v)) => Some(v), (None, None) => None, } } pub fn sum_options(a: Option, b: Option) -> Option where T: Add, { combine_options(a, b, |a, b| a + b) } pub fn min_options(a: Option, b: Option) -> Option where T: Ord, { combine_options(a, b, |a, b| a.min(b)) } pub fn max_options(a: Option, b: Option) -> Option where T: Ord, { combine_options(a, b, |a, b| a.max(b)) } #[cfg(test)] mod tests { use super::*; #[test] fn test_sum_options() { assert_eq!(sum_options(Some(1), Some(2)), Some(3)); assert_eq!(sum_options(Some(1), None), Some(1)); assert_eq!(sum_options(None, Some(2)), Some(2)); assert_eq!(sum_options::(None, None), None); assert_eq!(sum_options(Some(0.5), Some(0.25)), Some(0.75)); } }