diff --git a/corelib/src/option.cairo b/corelib/src/option.cairo index 42649c191dd..35bd953302b 100644 --- a/corelib/src/option.cairo +++ b/corelib/src/option.cairo @@ -617,6 +617,32 @@ pub trait OptionTrait { fn filter[Output: bool], +Destruct, +Destruct

>( self: Option, predicate: P, ) -> Option; + + /// Converts from `Option>` to `Option`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let x: Option> = Some(Some(6)); + /// assert_eq!(Some(6), x.flatten()); + /// + /// let x: Option> = Some(None); + /// assert_eq!(None, x.flatten()); + /// + /// let x: Option> = None; + /// assert_eq!(None, x.flatten()); + /// ``` + /// + /// Flattening only removes one level of nesting at a time: + /// + /// ``` + /// let x: Option>> = Some(Some(Some(6))); + /// assert_eq!(Some(Some(6)), x.flatten()); + /// assert_eq!(Some(6), x.flatten().flatten()); + /// ``` + fn flatten(self: Option>) -> Option; } pub impl OptionTraitImpl of OptionTrait { @@ -816,6 +842,14 @@ pub impl OptionTraitImpl of OptionTrait { None } + + #[inline] + fn flatten(self: Option>) -> Option { + match self { + Some(x) => x, + None => None, + } + } } diff --git a/corelib/src/test/option_test.cairo b/corelib/src/test/option_test.cairo index 4d09ee04d0a..6783c9e822b 100644 --- a/corelib/src/test/option_test.cairo +++ b/corelib/src/test/option_test.cairo @@ -280,3 +280,19 @@ fn test_option_filter() { assert!(Some(3).filter(is_even) == None); assert!(Some(4).filter(is_even) == Some(4)); } + +#[test] +fn test_option_flatten() { + let x: Option> = Some(Some(6)); + assert_eq!(Some(6), x.flatten()); + + let x: Option> = Some(None); + assert_eq!(None, x.flatten()); + + let x: Option> = None; + assert_eq!(None, x.flatten()); + + let x: Option>> = Some(Some(Some(6))); + assert_eq!(Some(Some(6)), x.flatten()); + assert_eq!(Some(6), x.flatten().flatten()); +}