@@ -445,8 +445,42 @@ impl AlgebraicType {
445445 _ => true ,
446446 }
447447 }
448- }
449448
449+ pub fn type_check ( & self , value : & AlgebraicValue ) -> bool {
450+ match value {
451+ AlgebraicValue :: Min | AlgebraicValue :: Max => return false ,
452+ _ => { }
453+ }
454+
455+ match self {
456+ AlgebraicType :: String => matches ! ( value, AlgebraicValue :: String ( _) ) ,
457+ AlgebraicType :: Bool => matches ! ( value, AlgebraicValue :: Bool ( _) ) ,
458+ AlgebraicType :: I8 => matches ! ( value, AlgebraicValue :: I8 ( _) ) ,
459+ AlgebraicType :: U8 => matches ! ( value, AlgebraicValue :: U8 ( _) ) ,
460+ AlgebraicType :: I16 => matches ! ( value, AlgebraicValue :: I16 ( _) ) ,
461+ AlgebraicType :: U16 => matches ! ( value, AlgebraicValue :: U16 ( _) ) ,
462+ AlgebraicType :: I32 => matches ! ( value, AlgebraicValue :: I32 ( _) ) ,
463+ AlgebraicType :: U32 => matches ! ( value, AlgebraicValue :: U32 ( _) ) ,
464+ AlgebraicType :: I64 => matches ! ( value, AlgebraicValue :: I64 ( _) ) ,
465+ AlgebraicType :: U64 => matches ! ( value, AlgebraicValue :: U64 ( _) ) ,
466+ AlgebraicType :: I128 => matches ! ( value, AlgebraicValue :: I128 ( _) ) ,
467+ AlgebraicType :: U128 => matches ! ( value, AlgebraicValue :: U128 ( _) ) ,
468+ AlgebraicType :: I256 => matches ! ( value, AlgebraicValue :: I256 ( _) ) ,
469+ AlgebraicType :: U256 => matches ! ( value, AlgebraicValue :: U256 ( _) ) ,
470+ AlgebraicType :: F32 => matches ! ( value, AlgebraicValue :: F32 ( _) ) ,
471+ AlgebraicType :: F64 => matches ! ( value, AlgebraicValue :: F64 ( _) ) ,
472+
473+ AlgebraicType :: Sum ( sum_ty) => sum_ty. type_check ( value) ,
474+ AlgebraicType :: Product ( product_ty) => product_ty. type_check ( value) ,
475+ AlgebraicType :: Array ( element_ty) => element_ty. type_check ( value) ,
476+
477+ AlgebraicType :: Ref ( _) => {
478+ // We cannot type check a Ref without the Typespace context
479+ false
480+ }
481+ }
482+ }
483+ }
450484#[ cfg( test) ]
451485mod tests {
452486 use super :: AlgebraicType ;
@@ -456,7 +490,7 @@ mod tests {
456490 algebraic_type:: fmt:: fmt_algebraic_type, algebraic_type:: map_notation:: fmt_algebraic_type as fmt_map,
457491 algebraic_type_ref:: AlgebraicTypeRef , typespace:: Typespace ,
458492 } ;
459- use crate :: { ValueWithType , WithTypespace } ;
493+ use crate :: { product , AlgebraicValue , ValueWithType , WithTypespace } ;
460494
461495 #[ test]
462496 fn never ( ) {
@@ -702,4 +736,22 @@ mod tests {
702736 assert ! ( AlgebraicType :: time_duration( ) . is_special( ) ) ;
703737 assert ! ( AlgebraicType :: time_duration( ) . is_time_duration( ) ) ;
704738 }
739+
740+ #[ test]
741+ fn type_check ( ) {
742+ let av = AlgebraicValue :: sum ( 1 , AlgebraicValue :: from ( product ! [ 0u16 , 1u32 ] ) ) ;
743+ let at = AlgebraicType :: sum ( [
744+ ( "a" , AlgebraicType :: U8 ) ,
745+ (
746+ "b" ,
747+ AlgebraicType :: Product ( crate :: ProductType :: new (
748+ [ AlgebraicType :: U16 . into ( ) , AlgebraicType :: U32 . into ( ) ]
749+ . to_vec ( )
750+ . into_boxed_slice ( ) ,
751+ ) ) ,
752+ ) ,
753+ ] ) ;
754+
755+ at. type_check ( & av) ;
756+ }
705757}
0 commit comments