1#![doc(hidden)]
18
19#[doc(hidden)]
23pub mod internal {
24 use crate::{
25 description::Description,
26 matcher::{Matcher, MatcherBase, MatcherResult},
27 };
28 use std::fmt::Debug;
29
30 impl MatcherBase for () {}
31
32 impl Matcher<()> for () {
35 fn matches(&self, _: ()) -> MatcherResult {
36 MatcherResult::Match
37 }
38
39 fn describe(&self, matcher_result: MatcherResult) -> Description {
40 match matcher_result {
41 MatcherResult::Match => "is the empty tuple".into(),
42 MatcherResult::NoMatch => "is not the empty tuple".into(),
43 }
44 }
45 }
46
47 impl Matcher<&()> for () {
48 fn matches(&self, _: &()) -> MatcherResult {
49 MatcherResult::Match
50 }
51
52 fn describe(&self, matcher_result: MatcherResult) -> Description {
53 <Self as Matcher<()>>::describe(self, matcher_result)
54 }
55 }
56
57 #[doc(hidden)]
61 macro_rules! tuple_matcher_n {
62 ($([$field_number:tt, $matcher_type:ident, $field_type:ident]),*) => {
63 impl<$($matcher_type: MatcherBase),*> MatcherBase for ($($matcher_type,)*){}
64
65 impl<$($field_type: Debug + Copy, $matcher_type: Matcher<$field_type>),*>
66 Matcher<($($field_type,)*)> for ($($matcher_type,)*)
67 {
68 fn matches(&self, actual: ($($field_type,)*)) -> MatcherResult {
69 $(match self.$field_number.matches(actual.$field_number) {
70 MatcherResult::Match => {},
71 MatcherResult::NoMatch => {
72 return MatcherResult::NoMatch;
73 }
74 })*
75 MatcherResult::Match
76 }
77
78 fn explain_match(&self, actual: ($($field_type,)*)) -> Description {
79 let mut explanation = Description::new().text("which").nested(
80 self.describe(self.matches(actual)));
81 $(match self.$field_number.matches(actual.$field_number) {
82 MatcherResult::Match => {},
83 MatcherResult::NoMatch => {
84 explanation = explanation
85 .text(format!(concat!("Element #", $field_number, " is {:?},"),
86 actual.$field_number))
87 .nested(self.$field_number.explain_match(actual.$field_number));
88 }
89 })*
90 explanation
91 }
92
93 fn describe(&self, matcher_result: MatcherResult) -> Description {
94 match matcher_result {
95 MatcherResult::Match => {
96 let mut description = Description::new().text(
97 "is a tuple whose values respectively match:");
98 $(description = description.nested(
99 self.$field_number.describe(matcher_result));)*
100 description
101 }
102 MatcherResult::NoMatch => {
103 let mut description = Description::new().text(
104 "is a tuple whose values do not respectively match:");
105 $(description = description.nested(
106 self.$field_number.describe(MatcherResult::Match));)*
107 description
108 }
109 }
110 }
111 }
112 impl<'a, $($field_type: Debug, $matcher_type: Matcher<&'a $field_type>),*>
113 Matcher<&'a ($($field_type,)*)> for ($($matcher_type,)*)
114 {
115 fn matches(&self, actual: &'a ($($field_type,)*)) -> MatcherResult {
116 $(match self.$field_number.matches(&actual.$field_number) {
117 MatcherResult::Match => {},
118 MatcherResult::NoMatch => {
119 return MatcherResult::NoMatch;
120 }
121 })*
122 MatcherResult::Match
123 }
124
125 fn explain_match(&self, actual: &'a ($($field_type,)*)) -> Description {
126 let mut explanation = Description::new()
127 .text("which")
128 .nested(
129 Matcher::<&'a ($($field_type,)*)>::describe(
130 self, self.matches(actual)));
131 $(match self.$field_number.matches(&actual.$field_number) {
132 MatcherResult::Match => {},
133 MatcherResult::NoMatch => {
134 explanation = explanation
135 .text(format!(
136 concat!(
137 "Element #",
138 $field_number,
139 " is {:?},"),
140 actual.$field_number))
141 .nested(self.$field_number.explain_match(&actual.$field_number));
142 }
143 })*
144 explanation
145 }
146
147 fn describe(&self, matcher_result: MatcherResult) -> Description {
148 match matcher_result {
149 MatcherResult::Match => {
150 let mut description = Description::new().text(
151 "is a tuple whose values respectively match:");
152 $(description = description.nested(
153 self.$field_number.describe(matcher_result));)*
154 description
155 }
156 MatcherResult::NoMatch => {
157 let mut description = Description::new().text(
158 "is a tuple whose values do not respectively match:");
159 $(description = description.nested(
160 self.$field_number.describe(MatcherResult::Match));)*
161 description
162 }
163 }
164 }
165 }
166 };
167 }
168
169 tuple_matcher_n!([0, I0, T0]);
170
171 tuple_matcher_n!([0, I0, T0], [1, I1, T1]);
172
173 tuple_matcher_n!([0, I0, T0], [1, I1, T1], [2, I2, T2]);
174
175 tuple_matcher_n!([0, I0, T0], [1, I1, T1], [2, I2, T2], [3, I3, T3]);
176
177 tuple_matcher_n!([0, I0, T0], [1, I1, T1], [2, I2, T2], [3, I3, T3], [4, I4, T4]);
178
179 tuple_matcher_n!([0, I0, T0], [1, I1, T1], [2, I2, T2], [3, I3, T3], [4, I4, T4], [5, I5, T5]);
180
181 tuple_matcher_n!(
182 [0, I0, T0],
183 [1, I1, T1],
184 [2, I2, T2],
185 [3, I3, T3],
186 [4, I4, T4],
187 [5, I5, T5],
188 [6, I6, T6]
189 );
190
191 tuple_matcher_n!(
192 [0, I0, T0],
193 [1, I1, T1],
194 [2, I2, T2],
195 [3, I3, T3],
196 [4, I4, T4],
197 [5, I5, T5],
198 [6, I6, T6],
199 [7, I7, T7]
200 );
201
202 tuple_matcher_n!(
203 [0, I0, T0],
204 [1, I1, T1],
205 [2, I2, T2],
206 [3, I3, T3],
207 [4, I4, T4],
208 [5, I5, T5],
209 [6, I6, T6],
210 [7, I7, T7],
211 [8, I8, T8]
212 );
213
214 tuple_matcher_n!(
215 [0, I0, T0],
216 [1, I1, T1],
217 [2, I2, T2],
218 [3, I3, T3],
219 [4, I4, T4],
220 [5, I5, T5],
221 [6, I6, T6],
222 [7, I7, T7],
223 [8, I8, T8],
224 [9, I9, T9]
225 );
226
227 tuple_matcher_n!(
228 [0, I0, T0],
229 [1, I1, T1],
230 [2, I2, T2],
231 [3, I3, T3],
232 [4, I4, T4],
233 [5, I5, T5],
234 [6, I6, T6],
235 [7, I7, T7],
236 [8, I8, T8],
237 [9, I9, T9],
238 [10, I10, T10]
239 );
240
241 tuple_matcher_n!(
242 [0, I0, T0],
243 [1, I1, T1],
244 [2, I2, T2],
245 [3, I3, T3],
246 [4, I4, T4],
247 [5, I5, T5],
248 [6, I6, T6],
249 [7, I7, T7],
250 [8, I8, T8],
251 [9, I9, T9],
252 [10, I10, T10],
253 [11, I11, T11]
254 );
255}