@@ -91,6 +91,9 @@ use common::{
91
91
} ,
92
92
pii:: PII ,
93
93
} ;
94
+ use convex_fivetran_source:: api_types:: selection as serialized;
95
+ #[ cfg( test) ]
96
+ use proptest:: prelude:: * ;
94
97
#[ cfg( test) ]
95
98
use proptest_derive:: Arbitrary ;
96
99
use value:: {
@@ -104,6 +107,11 @@ use value::{
104
107
pub struct StreamingExportSelection {
105
108
/// For each listed component, defines what to do with it in the
106
109
/// streaming export.
110
+ #[ cfg_attr(
111
+ test,
112
+ proptest( strategy = "prop::collection::btree_map(any::<ComponentPath>(), \
113
+ any::<StreamingExportComponentSelection>(), 0..3)")
114
+ ) ]
107
115
pub components : BTreeMap < ComponentPath , StreamingExportComponentSelection > ,
108
116
109
117
/// Whether to include components that are not listed in `components`.
@@ -187,6 +195,11 @@ impl StreamingExportSelection {
187
195
pub enum StreamingExportComponentSelection {
188
196
Excluded ,
189
197
Included {
198
+ #[ cfg_attr(
199
+ test,
200
+ proptest( strategy = "prop::collection::btree_map(any::<TableName>(), \
201
+ any::<StreamingExportTableSelection>(), 0..3)")
202
+ ) ]
190
203
tables : BTreeMap < TableName , StreamingExportTableSelection > ,
191
204
other_tables : StreamingExportInclusionDefault ,
192
205
} ,
@@ -235,6 +248,11 @@ pub enum StreamingExportTableSelection {
235
248
/// columns.
236
249
#[ cfg_attr( test, derive( Clone , Eq , PartialEq , Debug , Arbitrary ) ) ]
237
250
pub struct StreamingExportColumnSelection {
251
+ #[ cfg_attr(
252
+ test,
253
+ proptest( strategy = "prop::collection::btree_map(any::<FieldName>(), \
254
+ any::<StreamingExportColumnInclusion>(), 0..3)")
255
+ ) ]
238
256
columns : BTreeMap < FieldName , StreamingExportColumnInclusion > ,
239
257
other_columns : StreamingExportInclusionDefault ,
240
258
}
@@ -443,6 +461,87 @@ mod tests_is_table_included {
443
461
}
444
462
}
445
463
464
+ impl TryFrom < serialized:: Selection > for StreamingExportSelection {
465
+ type Error = anyhow:: Error ;
466
+
467
+ fn try_from (
468
+ serialized:: Selection {
469
+ components,
470
+ other_components,
471
+ } : serialized:: Selection ,
472
+ ) -> Result < Self , Self :: Error > {
473
+ Ok ( Self {
474
+ components : components
475
+ . into_iter ( )
476
+ . map ( |( k, v) | -> anyhow:: Result < _ > { Ok ( ( k. parse ( ) ?, v. try_into ( ) ?) ) } )
477
+ . try_collect ( ) ?,
478
+ other_components : other_components. into ( ) ,
479
+ } )
480
+ }
481
+ }
482
+
483
+ impl From < serialized:: ColumnInclusion > for StreamingExportColumnInclusion {
484
+ fn from ( value : serialized:: ColumnInclusion ) -> Self {
485
+ match value {
486
+ serialized:: ColumnInclusion :: Excluded => Self :: Excluded ,
487
+ serialized:: ColumnInclusion :: Included => Self :: Included ,
488
+ }
489
+ }
490
+ }
491
+
492
+ impl TryFrom < serialized:: ComponentSelection > for StreamingExportComponentSelection {
493
+ type Error = anyhow:: Error ;
494
+
495
+ fn try_from ( value : serialized:: ComponentSelection ) -> Result < Self , Self :: Error > {
496
+ Ok ( match value {
497
+ serialized:: ComponentSelection :: Excluded => Self :: Excluded ,
498
+ serialized:: ComponentSelection :: Included {
499
+ tables,
500
+ other_tables,
501
+ } => Self :: Included {
502
+ tables : tables
503
+ . into_iter ( )
504
+ . map ( |( k, v) | -> anyhow:: Result < _ > { Ok ( ( k. parse ( ) ?, v. try_into ( ) ?) ) } )
505
+ . try_collect ( ) ?,
506
+ other_tables : other_tables. into ( ) ,
507
+ } ,
508
+ } )
509
+ }
510
+ }
511
+
512
+ impl TryFrom < serialized:: TableSelection > for StreamingExportTableSelection {
513
+ type Error = anyhow:: Error ;
514
+
515
+ fn try_from ( value : serialized:: TableSelection ) -> Result < Self , Self :: Error > {
516
+ Ok ( match value {
517
+ serialized:: TableSelection :: Excluded => Self :: Excluded ,
518
+ serialized:: TableSelection :: Included {
519
+ columns,
520
+ other_columns,
521
+ } => {
522
+ let column_selection = StreamingExportColumnSelection {
523
+ columns : columns
524
+ . into_iter ( )
525
+ . map ( |( k, v) | -> anyhow:: Result < _ > { Ok ( ( k. parse ( ) ?, v. into ( ) ) ) } )
526
+ . try_collect ( ) ?,
527
+ other_columns : other_columns. into ( ) ,
528
+ } ;
529
+
530
+ Self :: Included ( column_selection)
531
+ } ,
532
+ } )
533
+ }
534
+ }
535
+
536
+ impl From < serialized:: InclusionDefault > for StreamingExportInclusionDefault {
537
+ fn from ( value : serialized:: InclusionDefault ) -> Self {
538
+ match value {
539
+ serialized:: InclusionDefault :: Excluded => Self :: Excluded ,
540
+ serialized:: InclusionDefault :: Included => Self :: Included ,
541
+ }
542
+ }
543
+ }
544
+
446
545
#[ cfg( test) ]
447
546
mod tests_column_filtering {
448
547
use common:: document:: CreationTime ;
@@ -601,3 +700,95 @@ mod tests_column_filtering {
601
700
Ok ( ( ) )
602
701
}
603
702
}
703
+
704
+ #[ cfg( test) ]
705
+ mod tests_serialization {
706
+ use cmd_util:: env:: env_config;
707
+ use proptest:: prelude:: * ;
708
+
709
+ use super :: * ;
710
+
711
+ impl From < StreamingExportSelection > for serialized:: Selection {
712
+ fn from (
713
+ StreamingExportSelection {
714
+ components,
715
+ other_components,
716
+ } : StreamingExportSelection ,
717
+ ) -> Self {
718
+ Self {
719
+ components : components
720
+ . into_iter ( )
721
+ . map ( |( k, v) | ( k. to_string ( ) , v. into ( ) ) )
722
+ . collect ( ) ,
723
+ other_components : other_components. into ( ) ,
724
+ }
725
+ }
726
+ }
727
+
728
+ impl From < StreamingExportColumnInclusion > for serialized:: ColumnInclusion {
729
+ fn from ( value : StreamingExportColumnInclusion ) -> Self {
730
+ match value {
731
+ StreamingExportColumnInclusion :: Excluded => Self :: Excluded ,
732
+ StreamingExportColumnInclusion :: Included => Self :: Included ,
733
+ }
734
+ }
735
+ }
736
+
737
+ impl From < StreamingExportComponentSelection > for serialized:: ComponentSelection {
738
+ fn from ( value : StreamingExportComponentSelection ) -> Self {
739
+ match value {
740
+ StreamingExportComponentSelection :: Excluded => Self :: Excluded ,
741
+ StreamingExportComponentSelection :: Included {
742
+ tables,
743
+ other_tables,
744
+ } => Self :: Included {
745
+ tables : tables
746
+ . into_iter ( )
747
+ . map ( |( k, v) | ( k. to_string ( ) , v. into ( ) ) )
748
+ . collect ( ) ,
749
+ other_tables : other_tables. into ( ) ,
750
+ } ,
751
+ }
752
+ }
753
+ }
754
+
755
+ impl From < StreamingExportTableSelection > for serialized:: TableSelection {
756
+ fn from ( value : StreamingExportTableSelection ) -> Self {
757
+ match value {
758
+ StreamingExportTableSelection :: Excluded => Self :: Excluded ,
759
+ StreamingExportTableSelection :: Included ( StreamingExportColumnSelection {
760
+ columns,
761
+ other_columns,
762
+ } ) => Self :: Included {
763
+ columns : columns
764
+ . into_iter ( )
765
+ . map ( |( k, v) | ( k. to_string ( ) , v. into ( ) ) )
766
+ . collect ( ) ,
767
+ other_columns : other_columns. into ( ) ,
768
+ } ,
769
+ }
770
+ }
771
+ }
772
+
773
+ impl From < StreamingExportInclusionDefault > for serialized:: InclusionDefault {
774
+ fn from ( value : StreamingExportInclusionDefault ) -> Self {
775
+ match value {
776
+ StreamingExportInclusionDefault :: Excluded => Self :: Excluded ,
777
+ StreamingExportInclusionDefault :: Included => Self :: Included ,
778
+ }
779
+ }
780
+ }
781
+
782
+ proptest ! {
783
+ #![ proptest_config( ProptestConfig {
784
+ cases: 64 * env_config( "CONVEX_PROPTEST_MULTIPLIER" , 1 ) ,
785
+ failure_persistence: None , ..ProptestConfig :: default ( )
786
+ } ) ]
787
+ #[ test]
788
+ fn test_streaming_export_selection_roundtrip( value in any:: <StreamingExportSelection >( ) ) {
789
+ let serialized: serialized:: Selection = value. clone( ) . into( ) ;
790
+ let deserialized: StreamingExportSelection = serialized. try_into( ) . expect( "Can't roundtrip" ) ;
791
+ prop_assert_eq!( value, deserialized) ;
792
+ }
793
+ }
794
+ }
0 commit comments