@@ -22,10 +22,34 @@ use stringsimile_matcher::{
2222 } ,
2323} ;
2424
25+ /// Configuration for rules
26+ #[ derive( Debug , Clone , Serialize , Deserialize ) ]
27+ pub struct RuleConfig {
28+ #[ serde( flatten, default ) ]
29+ pub ( crate ) common : CommonRuleConfig ,
30+ #[ serde( flatten) ]
31+ pub ( crate ) rule_type : RuleTypeConfig ,
32+ }
33+
34+ /// Common configuration for rules
35+ #[ derive( Debug , Clone , Serialize , Deserialize ) ]
36+ pub struct CommonRuleConfig {
37+ #[ serde( default ) ]
38+ pub ( crate ) exit_on_match : bool ,
39+ }
40+
41+ impl From < & CommonRuleConfig > for stringsimile_matcher:: ruleset:: CommonRuleConfig {
42+ fn from ( value : & CommonRuleConfig ) -> Self {
43+ Self {
44+ exit_on_match : value. exit_on_match ,
45+ }
46+ }
47+ }
48+
2549#[ derive( Debug , Clone , Serialize , Deserialize ) ]
2650#[ serde( tag = "rule_type" , rename_all = "snake_case" , content = "values" ) ]
27- /// Configuration for rules
28- pub enum RuleConfig {
51+ /// Configuration for specific rule types
52+ pub enum RuleTypeConfig {
2953 /// Configuration for Levenshtein rule
3054 Levenshtein ( LevenshteinConfig ) ,
3155 /// Configuration for Hamming rule
@@ -130,48 +154,63 @@ impl RuleConfig {
130154 & self ,
131155 target_str : & str ,
132156 ignore_mismatch_metadata : bool ,
133- ) -> Result < Box < dyn GenericMatcherRule > , Error > {
134- Ok ( match self {
135- RuleConfig :: Levenshtein ( levenshtein_config) => Box :: new (
136- levenshtein_config
137- . build ( ignore_mismatch_metadata) ?
138- . into_generic_matcher ( ) ,
139- ) ,
140- RuleConfig :: Hamming ( hamming_config) => {
141- Box :: new ( hamming_config. build ( ) ?. into_generic_matcher ( ) )
142- }
143- RuleConfig :: Confusables => Box :: new ( ConfusablesConfig . build ( ) ?. into_generic_matcher ( ) ) ,
144- RuleConfig :: Jaro ( jaro_config) => Box :: new ( jaro_config. build ( ) ?. into_generic_matcher ( ) ) ,
145- RuleConfig :: JaroWinkler ( jaro_winkler_config) => {
146- Box :: new ( jaro_winkler_config. build ( ) ?. into_generic_matcher ( ) )
147- }
148- RuleConfig :: DamerauLevenshtein ( damerau_levenshtein_config) => {
149- Box :: new ( damerau_levenshtein_config. build ( ignore_mismatch_metadata) ?)
150- }
151- RuleConfig :: Soundex ( soundex_config) => {
152- Box :: new ( soundex_config. build ( target_str) ?. into_generic_matcher ( ) )
153- }
154- RuleConfig :: Metaphone ( metaphone_config) => {
155- Box :: new ( metaphone_config. build ( target_str) ?. into_generic_matcher ( ) )
156- }
157- RuleConfig :: Nysiis ( nysiis_config) => {
158- Box :: new ( nysiis_config. build ( target_str) ?. into_generic_matcher ( ) )
159- }
160- RuleConfig :: MatchRating => {
161- Box :: new ( MatchRatingConfig . build ( target_str) ?. into_generic_matcher ( ) )
162- }
163- RuleConfig :: Bitflip ( bitflip_config) => Box :: new (
164- bitflip_config
165- . clone ( )
166- . unwrap_or_default ( )
167- . build ( target_str) ?
168- . into_generic_matcher ( ) ,
169- ) ,
170- RuleConfig :: Regex ( regex_config) => {
171- Box :: new ( regex_config. build ( ) ?. into_generic_matcher ( ) )
172- }
173- RuleConfig :: Cidr ( cidr_config) => Box :: new ( cidr_config. build ( ) ?. into_generic_matcher ( ) ) ,
174- } )
157+ ) -> Result <
158+ (
159+ stringsimile_matcher:: ruleset:: CommonRuleConfig ,
160+ Box < dyn GenericMatcherRule > ,
161+ ) ,
162+ Error ,
163+ > {
164+ Ok ( (
165+ ( & self . common ) . into ( ) ,
166+ match & self . rule_type {
167+ RuleTypeConfig :: Levenshtein ( levenshtein_config) => Box :: new (
168+ levenshtein_config
169+ . build ( ignore_mismatch_metadata) ?
170+ . into_generic_matcher ( ) ,
171+ ) ,
172+ RuleTypeConfig :: Hamming ( hamming_config) => {
173+ Box :: new ( hamming_config. build ( ) ?. into_generic_matcher ( ) )
174+ }
175+ RuleTypeConfig :: Confusables => {
176+ Box :: new ( ConfusablesConfig . build ( ) ?. into_generic_matcher ( ) )
177+ }
178+ RuleTypeConfig :: Jaro ( jaro_config) => {
179+ Box :: new ( jaro_config. build ( ) ?. into_generic_matcher ( ) )
180+ }
181+ RuleTypeConfig :: JaroWinkler ( jaro_winkler_config) => {
182+ Box :: new ( jaro_winkler_config. build ( ) ?. into_generic_matcher ( ) )
183+ }
184+ RuleTypeConfig :: DamerauLevenshtein ( damerau_levenshtein_config) => {
185+ Box :: new ( damerau_levenshtein_config. build ( ignore_mismatch_metadata) ?)
186+ }
187+ RuleTypeConfig :: Soundex ( soundex_config) => {
188+ Box :: new ( soundex_config. build ( target_str) ?. into_generic_matcher ( ) )
189+ }
190+ RuleTypeConfig :: Metaphone ( metaphone_config) => {
191+ Box :: new ( metaphone_config. build ( target_str) ?. into_generic_matcher ( ) )
192+ }
193+ RuleTypeConfig :: Nysiis ( nysiis_config) => {
194+ Box :: new ( nysiis_config. build ( target_str) ?. into_generic_matcher ( ) )
195+ }
196+ RuleTypeConfig :: MatchRating => {
197+ Box :: new ( MatchRatingConfig . build ( target_str) ?. into_generic_matcher ( ) )
198+ }
199+ RuleTypeConfig :: Bitflip ( bitflip_config) => Box :: new (
200+ bitflip_config
201+ . clone ( )
202+ . unwrap_or_default ( )
203+ . build ( target_str) ?
204+ . into_generic_matcher ( ) ,
205+ ) ,
206+ RuleTypeConfig :: Regex ( regex_config) => {
207+ Box :: new ( regex_config. build ( ) ?. into_generic_matcher ( ) )
208+ }
209+ RuleTypeConfig :: Cidr ( cidr_config) => {
210+ Box :: new ( cidr_config. build ( ) ?. into_generic_matcher ( ) )
211+ }
212+ } ,
213+ ) )
175214 }
176215}
177216
@@ -491,7 +530,7 @@ mod tests {
491530 }
492531 "# ;
493532
494- let RuleConfig :: Levenshtein ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
533+ let RuleTypeConfig :: Levenshtein ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
495534 panic ! ( "Expected Levenshtein config" ) ;
496535 } ;
497536 assert_eq ! ( 3 , config. maximum_distance) ;
@@ -508,7 +547,7 @@ mod tests {
508547 }
509548 "# ;
510549
511- let RuleConfig :: Jaro ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
550+ let RuleTypeConfig :: Jaro ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
512551 panic ! ( "Expected Jaro config" ) ;
513552 } ;
514553 assert_eq ! ( 0.4 , config. match_percent_threshold) ;
@@ -522,7 +561,7 @@ mod tests {
522561 }
523562 "# ;
524563
525- let RuleConfig :: Confusables = serde_json:: from_str ( json) . unwrap ( ) else {
564+ let RuleTypeConfig :: Confusables = serde_json:: from_str ( json) . unwrap ( ) else {
526565 panic ! ( "Expected Confusables config" ) ;
527566 } ;
528567 }
@@ -538,7 +577,7 @@ mod tests {
538577 }
539578 "# ;
540579
541- let RuleConfig :: DamerauLevenshtein ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
580+ let RuleTypeConfig :: DamerauLevenshtein ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
542581 panic ! ( "Expected Damera Levenshtein config" ) ;
543582 } ;
544583 assert_eq ! ( 3 , config. maximum_distance) ;
@@ -555,7 +594,7 @@ mod tests {
555594 }
556595 "# ;
557596
558- let RuleConfig :: JaroWinkler ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
597+ let RuleTypeConfig :: JaroWinkler ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
559598 panic ! ( "Expected Jaro-Winkler config" ) ;
560599 } ;
561600 assert_eq ! ( 0.4 , config. match_percent_threshold) ;
@@ -572,7 +611,7 @@ mod tests {
572611 }
573612 "# ;
574613
575- let RuleConfig :: Hamming ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
614+ let RuleTypeConfig :: Hamming ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
576615 panic ! ( "Expected Hamming config" ) ;
577616 } ;
578617 assert_eq ! ( 3 , config. maximum_distance) ;
@@ -590,7 +629,7 @@ mod tests {
590629 }
591630 "# ;
592631
593- let RuleConfig :: Soundex ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
632+ let RuleTypeConfig :: Soundex ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
594633 panic ! ( "Expected Soundex config" ) ;
595634 } ;
596635 assert_eq ! ( 3 , config. minimum_similarity) ;
@@ -608,7 +647,7 @@ mod tests {
608647 }
609648 "# ;
610649
611- let RuleConfig :: Soundex ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
650+ let RuleTypeConfig :: Soundex ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
612651 panic ! ( "Expected Soundex config" ) ;
613652 } ;
614653 assert_eq ! ( 3 , config. minimum_similarity) ;
@@ -627,7 +666,7 @@ mod tests {
627666 }
628667 "# ;
629668
630- let RuleConfig :: Soundex ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
669+ let RuleTypeConfig :: Soundex ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
631670 panic ! ( "Expected Soundex config" ) ;
632671 } ;
633672 assert_eq ! ( 3 , config. minimum_similarity) ;
@@ -646,7 +685,7 @@ mod tests {
646685 }
647686 "# ;
648687
649- let RuleConfig :: Metaphone ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
688+ let RuleTypeConfig :: Metaphone ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
650689 panic ! ( "Expected Metaphone config" ) ;
651690 } ;
652691 assert_eq ! ( Some ( 3 ) , config. max_code_length) ;
@@ -662,7 +701,7 @@ mod tests {
662701 }
663702 "# ;
664703
665- let RuleConfig :: Metaphone ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
704+ let RuleTypeConfig :: Metaphone ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
666705 panic ! ( "Expected Metaphone config" ) ;
667706 } ;
668707 assert_eq ! ( Some ( 4 ) , config. max_code_length) ;
@@ -680,7 +719,7 @@ mod tests {
680719 }
681720 "# ;
682721
683- let RuleConfig :: Metaphone ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
722+ let RuleTypeConfig :: Metaphone ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
684723 panic ! ( "Expected Metaphone config" ) ;
685724 } ;
686725 assert_eq ! ( None , config. max_code_length) ;
@@ -698,7 +737,7 @@ mod tests {
698737 }
699738 "# ;
700739
701- let RuleConfig :: Metaphone ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
740+ let RuleTypeConfig :: Metaphone ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
702741 panic ! ( "Expected Metaphone config" ) ;
703742 } ;
704743 assert_eq ! ( default_metaphone_max_code_length( ) , config. max_code_length) ;
@@ -717,7 +756,7 @@ mod tests {
717756 }
718757 "# ;
719758
720- let RuleConfig :: Metaphone ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
759+ let RuleTypeConfig :: Metaphone ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
721760 panic ! ( "Expected Metaphone config" ) ;
722761 } ;
723762 assert_eq ! ( Some ( 3 ) , config. max_code_length) ;
@@ -735,7 +774,7 @@ mod tests {
735774 }
736775 "# ;
737776
738- let RuleConfig :: Nysiis ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
777+ let RuleTypeConfig :: Nysiis ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
739778 panic ! ( "Expected Nysiis config" ) ;
740779 } ;
741780 assert ! ( !config. strict) ;
@@ -750,7 +789,7 @@ mod tests {
750789 }
751790 "# ;
752791
753- let RuleConfig :: Nysiis ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
792+ let RuleTypeConfig :: Nysiis ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
754793 panic ! ( "Expected Nysiis config" ) ;
755794 } ;
756795 assert ! ( config. strict) ;
@@ -764,7 +803,7 @@ mod tests {
764803 }
765804 "# ;
766805
767- let RuleConfig :: MatchRating = serde_json:: from_str ( json) . unwrap ( ) else {
806+ let RuleTypeConfig :: MatchRating = serde_json:: from_str ( json) . unwrap ( ) else {
768807 panic ! ( "Expected Match Rating config" ) ;
769808 } ;
770809 }
@@ -777,7 +816,7 @@ mod tests {
777816 }
778817 "# ;
779818
780- let RuleConfig :: Bitflip ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
819+ let RuleTypeConfig :: Bitflip ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
781820 panic ! ( "Expected Biflip config" ) ;
782821 } ;
783822 let config = config. unwrap_or_default ( ) ;
@@ -798,7 +837,7 @@ mod tests {
798837 }
799838 "# ;
800839
801- let RuleConfig :: Bitflip ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
840+ let RuleTypeConfig :: Bitflip ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
802841 panic ! ( "Expected Biflip config" ) ;
803842 } ;
804843 let config = config. unwrap_or_default ( ) ;
@@ -820,7 +859,7 @@ mod tests {
820859 }
821860 "# ;
822861
823- let RuleConfig :: Bitflip ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
862+ let RuleTypeConfig :: Bitflip ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
824863 panic ! ( "Expected Biflip config" ) ;
825864 } ;
826865 let config = config. unwrap_or_default ( ) ;
@@ -842,7 +881,7 @@ mod tests {
842881 }
843882 "# ;
844883
845- let RuleConfig :: Bitflip ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
884+ let RuleTypeConfig :: Bitflip ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
846885 panic ! ( "Expected Biflip config" ) ;
847886 } ;
848887 let config = config. unwrap_or_default ( ) ;
@@ -869,7 +908,7 @@ mod tests {
869908 }
870909 "# ;
871910
872- let RuleConfig :: Regex ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
911+ let RuleTypeConfig :: Regex ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
873912 panic ! ( "Expected Regex config" ) ;
874913 } ;
875914 assert_eq ! ( config. pattern, "test" ) ;
@@ -889,7 +928,7 @@ mod tests {
889928 }
890929 "# ;
891930
892- let RuleConfig :: Regex ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
931+ let RuleTypeConfig :: Regex ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
893932 panic ! ( "Expected Regex config" ) ;
894933 } ;
895934 assert_eq ! ( config. pattern, "[" ) ;
@@ -909,7 +948,7 @@ mod tests {
909948 }
910949 "# ;
911950
912- let RuleConfig :: Cidr ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
951+ let RuleTypeConfig :: Cidr ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
913952 panic ! ( "Expected CIDR config" ) ;
914953 } ;
915954 assert_eq ! ( config. address, "192.168.0.0/24" ) ;
@@ -929,7 +968,7 @@ mod tests {
929968 }
930969 "# ;
931970
932- let RuleConfig :: Cidr ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
971+ let RuleTypeConfig :: Cidr ( config) = serde_json:: from_str ( json) . unwrap ( ) else {
933972 panic ! ( "Expected CIDR config" ) ;
934973 } ;
935974 assert_eq ! ( config. address, "test" ) ;
0 commit comments