55
55
#[ macro_export]
56
56
#[ doc( hidden) ]
57
57
macro_rules! __any {
58
- ( $( $matcher: expr) ,* $( , ) ?) => { {
59
- use $crate:: matchers:: __internal_unstable_do_not_depend_on_these:: AnyMatcher ;
60
- AnyMatcher :: new( [ $( Box :: new( $matcher) ) ,* ] )
58
+ ( $( , ) ?) => { {
59
+ std:: compile_error!( "any![...] expects at least one argument" ) ;
60
+ } } ;
61
+ ( $matcher: expr $( , ) ?) => { {
62
+ $matcher
63
+ } } ;
64
+ ( $head: expr, $head2: expr $( , ) ?) => { {
65
+ $crate:: matchers:: __internal_unstable_do_not_depend_on_these:: DisjunctionMatcher :: new( $head, $head2)
66
+ } } ;
67
+ ( $head: expr, $head2: expr, $( $tail: expr) ,+ $( , ) ?) => { {
68
+ $crate:: __any![
69
+ $crate:: matchers:: __internal_unstable_do_not_depend_on_these:: DisjunctionMatcher :: new( $head, $head2) ,
70
+ $( $tail) ,+
71
+ ]
61
72
} }
62
73
}
63
74
64
- /// Functionality needed by the [`any`] macro.
65
- ///
66
- /// For internal use only. API stablility is not guaranteed!
67
- #[ doc( hidden) ]
68
- pub mod internal {
69
- use crate :: description:: Description ;
70
- use crate :: matcher:: { Matcher , MatcherResult } ;
71
- use crate :: matchers:: anything;
72
- use std:: fmt:: Debug ;
73
-
74
- /// A matcher which matches an input value matched by all matchers in the
75
- /// array `components`.
76
- ///
77
- /// For internal use only. API stablility is not guaranteed!
78
- #[ doc( hidden) ]
79
- pub struct AnyMatcher < ' a , T : Debug + ?Sized , const N : usize > {
80
- components : [ Box < dyn Matcher < ActualT = T > + ' a > ; N ] ,
81
- }
82
-
83
- impl < ' a , T : Debug + ?Sized , const N : usize > AnyMatcher < ' a , T , N > {
84
- /// Constructs an [`AnyMatcher`] with the given component matchers.
85
- ///
86
- /// Intended for use only by the [`all`] macro.
87
- pub fn new ( components : [ Box < dyn Matcher < ActualT = T > + ' a > ; N ] ) -> Self {
88
- Self { components }
89
- }
90
- }
91
-
92
- impl < ' a , T : Debug + ?Sized , const N : usize > Matcher for AnyMatcher < ' a , T , N > {
93
- type ActualT = T ;
94
-
95
- fn matches ( & self , actual : & Self :: ActualT ) -> MatcherResult {
96
- MatcherResult :: from ( self . components . iter ( ) . any ( |c| c. matches ( actual) . is_match ( ) ) )
97
- }
98
-
99
- fn explain_match ( & self , actual : & Self :: ActualT ) -> Description {
100
- match N {
101
- 0 => format ! ( "which {}" , anything:: <T >( ) . describe( MatcherResult :: NoMatch ) ) . into ( ) ,
102
- 1 => self . components [ 0 ] . explain_match ( actual) ,
103
- _ => {
104
- let failures = self
105
- . components
106
- . iter ( )
107
- . filter ( |component| component. matches ( actual) . is_no_match ( ) )
108
- . collect :: < Vec < _ > > ( ) ;
109
-
110
- if failures. len ( ) == 1 {
111
- failures[ 0 ] . explain_match ( actual)
112
- } else {
113
- Description :: new ( )
114
- . collect (
115
- failures
116
- . into_iter ( )
117
- . map ( |component| component. explain_match ( actual) ) ,
118
- )
119
- . bullet_list ( )
120
- }
121
- }
122
- }
123
- }
124
-
125
- fn describe ( & self , matcher_result : MatcherResult ) -> Description {
126
- match N {
127
- 0 => anything :: < T > ( ) . describe ( matcher_result) ,
128
- 1 => self . components [ 0 ] . describe ( matcher_result) ,
129
- _ => {
130
- let properties = self
131
- . components
132
- . iter ( )
133
- . map ( |m| m. describe ( matcher_result) )
134
- . collect :: < Description > ( )
135
- . bullet_list ( )
136
- . indent ( ) ;
137
- format ! (
138
- "{}:\n {properties}" ,
139
- if matcher_result. into( ) {
140
- "has at least one of the following properties"
141
- } else {
142
- "has none of the following properties"
143
- }
144
- )
145
- . into ( )
146
- }
147
- }
148
- }
149
- }
150
- }
151
-
152
75
#[ cfg( test) ]
153
76
mod tests {
154
- use super :: internal;
155
77
use crate :: matcher:: { Matcher , MatcherResult } ;
156
78
use crate :: prelude:: * ;
157
79
use indoc:: indoc;
158
80
159
81
#[ test]
160
82
fn description_shows_more_than_one_matcher ( ) -> Result < ( ) > {
161
- let first_matcher = starts_with ( "A" ) ;
83
+ let first_matcher: StrMatcher < String , & str > = starts_with ( "A" ) ;
162
84
let second_matcher = ends_with ( "string" ) ;
163
- let matcher: internal :: AnyMatcher < String , 2 > = any ! ( first_matcher, second_matcher) ;
85
+ let matcher = any ! ( first_matcher, second_matcher) ;
164
86
165
87
verify_that ! (
166
88
matcher. describe( MatcherResult :: Match ) ,
@@ -175,8 +97,8 @@ mod tests {
175
97
176
98
#[ test]
177
99
fn description_shows_one_matcher_directly ( ) -> Result < ( ) > {
178
- let first_matcher = starts_with ( "A" ) ;
179
- let matcher: internal :: AnyMatcher < String , 1 > = any ! ( first_matcher) ;
100
+ let first_matcher: StrMatcher < String , & str > = starts_with ( "A" ) ;
101
+ let matcher = any ! ( first_matcher) ;
180
102
181
103
verify_that ! (
182
104
matcher. describe( MatcherResult :: Match ) ,
@@ -189,7 +111,7 @@ mod tests {
189
111
{
190
112
let first_matcher = starts_with ( "Another" ) ;
191
113
let second_matcher = ends_with ( "string" ) ;
192
- let matcher: internal :: AnyMatcher < str , 2 > = any ! ( first_matcher, second_matcher) ;
114
+ let matcher = any ! ( first_matcher, second_matcher) ;
193
115
194
116
verify_that ! (
195
117
matcher. explain_match( "A string" ) ,
@@ -200,7 +122,7 @@ mod tests {
200
122
#[ test]
201
123
fn mismatch_description_is_simple_when_only_one_constituent ( ) -> Result < ( ) > {
202
124
let first_matcher = starts_with ( "Another" ) ;
203
- let matcher: internal :: AnyMatcher < str , 1 > = any ! ( first_matcher) ;
125
+ let matcher = any ! ( first_matcher) ;
204
126
205
127
verify_that ! (
206
128
matcher. explain_match( "A string" ) ,
0 commit comments