@@ -257,6 +257,21 @@ impl SumType {
257
257
}
258
258
}
259
259
260
+ /// If the sum matches the convention of `Option[row]`, return the row.
261
+ pub fn as_option ( & self ) -> Option < & TypeRowRV > {
262
+ match self {
263
+ SumType :: Unit { size } if * size == 2 => Some ( TypeRV :: EMPTY_TYPEROW_REF ) ,
264
+ SumType :: General { rows } if rows. len ( ) == 2 && rows[ 0 ] . is_empty ( ) => Some ( & rows[ 1 ] ) ,
265
+ _ => None ,
266
+ }
267
+ }
268
+
269
+ /// If a sum is an option of a single type, return the type.
270
+ pub fn as_unary_option ( & self ) -> Option < & TypeRV > {
271
+ self . as_option ( )
272
+ . and_then ( |row| ( row. len ( ) == 1 ) . then_some ( & row[ 0 ] ) )
273
+ }
274
+
260
275
/// Returns an iterator over the variants.
261
276
pub fn variants ( & self ) -> impl Iterator < Item = & TypeRowRV > {
262
277
match self {
@@ -790,7 +805,7 @@ pub(crate) mod test {
790
805
use std:: sync:: Weak ;
791
806
792
807
use super :: * ;
793
- use crate :: extension:: prelude:: { qb_t, usize_t} ;
808
+ use crate :: extension:: prelude:: { option_type , qb_t, usize_t} ;
794
809
use crate :: extension:: TypeDefBound ;
795
810
use crate :: std_extensions:: collections:: array:: { array_type, array_type_parametric} ;
796
811
use crate :: std_extensions:: collections:: list:: list_type;
@@ -835,6 +850,13 @@ pub(crate) mod test {
835
850
assert ! ( t. as_sum( ) . is_some( ) ) ;
836
851
}
837
852
853
+ #[ test]
854
+ fn as_option ( ) {
855
+ let opt = option_type ( usize_t ( ) ) ;
856
+
857
+ assert_eq ! ( opt. as_unary_option( ) . unwrap( ) . clone( ) , usize_t( ) ) ;
858
+ }
859
+
838
860
#[ test]
839
861
fn as_extension ( ) {
840
862
assert_eq ! (
0 commit comments