Skip to content

Commit 9671ce5

Browse files
authored
feat: utilities for casting sum types to option (#2154)
1 parent 7a95561 commit 9671ce5

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

hugr-core/src/types.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,21 @@ impl SumType {
257257
}
258258
}
259259

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+
260275
/// Returns an iterator over the variants.
261276
pub fn variants(&self) -> impl Iterator<Item = &TypeRowRV> {
262277
match self {
@@ -790,7 +805,7 @@ pub(crate) mod test {
790805
use std::sync::Weak;
791806

792807
use super::*;
793-
use crate::extension::prelude::{qb_t, usize_t};
808+
use crate::extension::prelude::{option_type, qb_t, usize_t};
794809
use crate::extension::TypeDefBound;
795810
use crate::std_extensions::collections::array::{array_type, array_type_parametric};
796811
use crate::std_extensions::collections::list::list_type;
@@ -835,6 +850,13 @@ pub(crate) mod test {
835850
assert!(t.as_sum().is_some());
836851
}
837852

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+
838860
#[test]
839861
fn as_extension() {
840862
assert_eq!(

0 commit comments

Comments
 (0)