1#![doc(hidden)]
19
20#[doc(hidden)]
24pub mod __internal {
25 use crate::{
26 description::Description,
27 matcher::{Describable, Matcher, MatcherResult},
28 };
29 use core::fmt::Debug;
30
31 impl Matcher<()> for () {
34 fn matches(&self, _: &()) -> MatcherResult {
35 MatcherResult::Match
36 }
37 }
38
39 impl Describable for () {
40 fn describe(&self, matcher_result: MatcherResult) -> Description {
41 match matcher_result {
42 MatcherResult::Match => "is the empty tuple".into(),
43 MatcherResult::NoMatch => "is not the empty tuple".into(),
44 }
45 }
46 }
47
48 #[doc(hidden)]
52 macro_rules! tuple_matcher_n {
53 ($([$field_number:tt, $matcher_type:ident, $field_type:ident]),*) => {
54 impl<$($field_type: Debug, $matcher_type: Matcher<$field_type>),*>
55 Matcher<($($field_type,)*)> for ($($matcher_type,)*)
56 {
57 fn matches(&self, actual: &($($field_type,)*)) -> MatcherResult {
58 $(match self.$field_number.matches(&actual.$field_number) {
59 MatcherResult::Match => {},
60 MatcherResult::NoMatch => {
61 return MatcherResult::NoMatch;
62 }
63 })*
64 MatcherResult::Match
65 }
66
67 fn explain_match(&self, actual: &($($field_type,)*)) -> Description {
68 let mut explanation = Description::new().text("which").nested(self.describe(self.matches(actual)));
69 $(match self.$field_number.matches(&actual.$field_number) {
70 MatcherResult::Match => {},
71 MatcherResult::NoMatch => {
72 explanation = explanation
73 .text(format!(concat!("Element #", $field_number, " is {:?},"), actual.$field_number))
74 .nested(self.$field_number.explain_match(&actual.$field_number));
75 }
76 })*
77 explanation
78 }
79
80 }
81
82 impl<$($matcher_type: Describable),*> Describable for ($($matcher_type,)*) {
83 fn describe(&self, matcher_result: MatcherResult) -> Description {
84 match matcher_result {
85 MatcherResult::Match => {
86 let mut description = Description::new().text("is a tuple whose values respectively match:");
87 $(description = description.nested(self.$field_number.describe(matcher_result));)*
88 description
89 }
90 MatcherResult::NoMatch => {
91 let mut description = Description::new().text("is a tuple whose values do not respectively match:");
92 $(description = description.nested(self.$field_number.describe(MatcherResult::Match));)*
93 description
94 }
95 }
96 }
97 }
98 };
99 }
100
101 tuple_matcher_n!([0, I0, T0]);
102
103 tuple_matcher_n!([0, I0, T0], [1, I1, T1]);
104
105 tuple_matcher_n!([0, I0, T0], [1, I1, T1], [2, I2, T2]);
106
107 tuple_matcher_n!([0, I0, T0], [1, I1, T1], [2, I2, T2], [3, I3, T3]);
108
109 tuple_matcher_n!([0, I0, T0], [1, I1, T1], [2, I2, T2], [3, I3, T3], [4, I4, T4]);
110
111 tuple_matcher_n!([0, I0, T0], [1, I1, T1], [2, I2, T2], [3, I3, T3], [4, I4, T4], [5, I5, T5]);
112
113 tuple_matcher_n!(
114 [0, I0, T0],
115 [1, I1, T1],
116 [2, I2, T2],
117 [3, I3, T3],
118 [4, I4, T4],
119 [5, I5, T5],
120 [6, I6, T6]
121 );
122
123 tuple_matcher_n!(
124 [0, I0, T0],
125 [1, I1, T1],
126 [2, I2, T2],
127 [3, I3, T3],
128 [4, I4, T4],
129 [5, I5, T5],
130 [6, I6, T6],
131 [7, I7, T7]
132 );
133
134 tuple_matcher_n!(
135 [0, I0, T0],
136 [1, I1, T1],
137 [2, I2, T2],
138 [3, I3, T3],
139 [4, I4, T4],
140 [5, I5, T5],
141 [6, I6, T6],
142 [7, I7, T7],
143 [8, I8, T8]
144 );
145
146 tuple_matcher_n!(
147 [0, I0, T0],
148 [1, I1, T1],
149 [2, I2, T2],
150 [3, I3, T3],
151 [4, I4, T4],
152 [5, I5, T5],
153 [6, I6, T6],
154 [7, I7, T7],
155 [8, I8, T8],
156 [9, I9, T9]
157 );
158
159 tuple_matcher_n!(
160 [0, I0, T0],
161 [1, I1, T1],
162 [2, I2, T2],
163 [3, I3, T3],
164 [4, I4, T4],
165 [5, I5, T5],
166 [6, I6, T6],
167 [7, I7, T7],
168 [8, I8, T8],
169 [9, I9, T9],
170 [10, I10, T10]
171 );
172
173 tuple_matcher_n!(
174 [0, I0, T0],
175 [1, I1, T1],
176 [2, I2, T2],
177 [3, I3, T3],
178 [4, I4, T4],
179 [5, I5, T5],
180 [6, I6, T6],
181 [7, I7, T7],
182 [8, I8, T8],
183 [9, I9, T9],
184 [10, I10, T10],
185 [11, I11, T11]
186 );
187}