@@ -9,7 +9,7 @@ use std::hash::{Hash, Hasher};
9
9
use super :: { NamedOp , OpName , OpTrait , StaticTag } ;
10
10
use super :: { OpTag , OpType } ;
11
11
use crate :: extension:: ExtensionSet ;
12
- use crate :: types:: { CustomType , EdgeKind , Signature , SumType , SumTypeError , Type } ;
12
+ use crate :: types:: { CustomType , EdgeKind , Signature , SumType , SumTypeError , Type , TypeRow } ;
13
13
use crate :: { Hugr , HugrView } ;
14
14
15
15
use delegate:: delegate;
@@ -450,6 +450,21 @@ impl Value {
450
450
Self :: unit_sum ( 0 , 2 ) . expect ( "0 < 2" )
451
451
}
452
452
453
+ /// Returns an optional with some values. This is a Sum with two variants, the
454
+ /// first being empty and the second being the values.
455
+ pub fn some < V : Into < Value > > ( values : impl IntoIterator < Item = V > ) -> Self {
456
+ let values: Vec < Value > = values. into_iter ( ) . map ( Into :: into) . collect_vec ( ) ;
457
+ let value_types: Vec < Type > = values. iter ( ) . map ( |v| v. get_type ( ) ) . collect_vec ( ) ;
458
+ let sum_type = SumType :: new_option ( value_types) ;
459
+ Self :: sum ( 1 , values, sum_type) . unwrap ( )
460
+ }
461
+
462
+ /// Returns an optional with no value. This is a Sum with two variants, the
463
+ /// first being empty and the second being the value.
464
+ pub fn none ( value_types : impl Into < TypeRow > ) -> Self {
465
+ Self :: sum ( 0 , [ ] , SumType :: new_option ( value_types) ) . unwrap ( )
466
+ }
467
+
453
468
/// Returns a constant `bool` value.
454
469
///
455
470
/// see [`Value::true_val`] and [`Value::false_val`].
@@ -753,16 +768,29 @@ pub(crate) mod test {
753
768
}
754
769
755
770
#[ fixture]
756
- fn const_array_2_bool ( ) -> Value {
771
+ fn const_array_bool ( ) -> Value {
757
772
ArrayValue :: new ( bool_t ( ) , [ Value :: true_val ( ) , Value :: false_val ( ) ] ) . into ( )
758
773
}
759
774
775
+ #[ fixture]
776
+ fn const_array_options ( ) -> Value {
777
+ let some_true = Value :: some ( [ Value :: true_val ( ) ] ) ;
778
+ let none = Value :: none ( vec ! [ bool_t( ) ] ) ;
779
+ let elem_ty = SumType :: new_option ( vec ! [ bool_t( ) ] ) ;
780
+ ArrayValue :: new ( elem_ty. into ( ) , [ some_true, none] ) . into ( )
781
+ }
782
+
760
783
#[ rstest]
761
784
#[ case( Value :: unit( ) , Type :: UNIT , "const:seq:{}" ) ]
762
785
#[ case( const_usize( ) , usize_t( ) , "const:custom:ConstUsize(" ) ]
763
786
#[ case( serialized_float( 17.4 ) , float64_type( ) , "const:custom:json:Object" ) ]
764
787
#[ case( const_tuple( ) , Type :: new_tuple( vec![ usize_t( ) , bool_t( ) ] ) , "const:seq:{" ) ]
765
- #[ case( const_array_2_bool( ) , array_type( 2 , bool_t( ) ) , "const:custom:array" ) ]
788
+ #[ case( const_array_bool( ) , array_type( 2 , bool_t( ) ) , "const:custom:array" ) ]
789
+ #[ case(
790
+ const_array_options( ) ,
791
+ array_type( 2 , SumType :: new_option( vec![ bool_t( ) ] ) . into( ) ) ,
792
+ "const:custom:array"
793
+ ) ]
766
794
fn const_type (
767
795
#[ case] const_value : Value ,
768
796
#[ case] expected_type : Type ,
@@ -781,7 +809,8 @@ pub(crate) mod test {
781
809
#[ case( const_usize( ) , const_usize( ) ) ]
782
810
#[ case( const_serialized_usize( ) , const_usize( ) ) ]
783
811
#[ case( const_tuple_serialized( ) , const_tuple( ) ) ]
784
- #[ case( const_array_2_bool( ) , const_array_2_bool( ) ) ]
812
+ #[ case( const_array_bool( ) , const_array_bool( ) ) ]
813
+ #[ case( const_array_options( ) , const_array_options( ) ) ]
785
814
fn const_serde_roundtrip ( #[ case] const_value : Value , #[ case] expected_value : Value ) {
786
815
let serialized = serde_json:: to_string ( & const_value) . unwrap ( ) ;
787
816
let deserialized: Value = serde_json:: from_str ( & serialized) . unwrap ( ) ;
0 commit comments