asserting/expectation_combinators/
mod.rs1use crate::expectations::{All, Any, IntoRec, Not, Rec};
2use crate::spec::{DiffFormat, Expectation, Expression, Invertible};
3use crate::std::string::String;
4
5impl<S, E> Expectation<S> for Rec<E>
6where
7 E: Expectation<S>,
8{
9 fn test(&mut self, subject: &S) -> bool {
10 let result = self.expectation.test(subject);
11 self.result = Some(result);
12 result
13 }
14
15 fn message(
16 &self,
17 expression: &Expression<'_>,
18 actual: &S,
19 inverted: bool,
20 format: &DiffFormat,
21 ) -> String {
22 if self.is_failure() {
23 self.expectation
24 .message(expression, actual, inverted, format)
25 + "\n"
26 } else {
27 String::new()
28 }
29 }
30}
31
32impl<E> From<E> for Rec<E> {
33 fn from(expectation: E) -> Self {
34 Self::new(expectation)
35 }
36}
37
38macro_rules! impl_into_rec_for_tuple {
39 ( $( $tp_name:ident )+ ) => {
40 #[allow(non_snake_case)]
41 impl<$($tp_name: Into<Rec<$tp_name >>),+> IntoRec for ($($tp_name,)+) {
42 type Output = ($(Rec<$tp_name>,)+);
43
44 fn into_rec(self) -> Self::Output {
45 let ($($tp_name,)+) = self;
46 ($($tp_name.into(),)+)
47 }
48 }
49 };
50}
51
52impl_into_rec_for_tuple! { A1 }
53impl_into_rec_for_tuple! { A1 A2 }
54impl_into_rec_for_tuple! { A1 A2 A3 }
55impl_into_rec_for_tuple! { A1 A2 A3 A4 }
56impl_into_rec_for_tuple! { A1 A2 A3 A4 A5 }
57impl_into_rec_for_tuple! { A1 A2 A3 A4 A5 A6 }
58impl_into_rec_for_tuple! { A1 A2 A3 A4 A5 A6 A7 }
59impl_into_rec_for_tuple! { A1 A2 A3 A4 A5 A6 A7 A8 }
60impl_into_rec_for_tuple! { A1 A2 A3 A4 A5 A6 A7 A8 A9 }
61impl_into_rec_for_tuple! { A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 }
62impl_into_rec_for_tuple! { A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 }
63impl_into_rec_for_tuple! { A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 }
64
65impl<S, E> Expectation<S> for Not<E>
66where
67 E: Invertible + Expectation<S>,
68{
69 fn test(&mut self, subject: &S) -> bool {
70 !self.0.test(subject)
71 }
72
73 fn message(
74 &self,
75 expression: &Expression<'_>,
76 actual: &S,
77 inverted: bool,
78 format: &DiffFormat,
79 ) -> String {
80 self.0.message(expression, actual, !inverted, format)
81 }
82}
83
84macro_rules! impl_expectation_for_all_combinator {
85 ( $( $tp_name:ident )+ ) => {
86 #[allow(non_snake_case)]
87 impl<S, $($tp_name: Expectation<S>),+> Expectation<S> for All<($(Rec<$tp_name>,)+)> {
88 fn test(&mut self, subject: &S) -> bool {
89 let ($($tp_name,)+) = &mut self.0;
90 $(
91 let $tp_name = $tp_name.test(subject);
92 )+
93 $( $tp_name )&&+
94 }
95
96 fn message(
97 &self,
98 expression: &Expression<'_>,
99 actual: &S,
100 inverted: bool,
101 format: &DiffFormat,
102 ) -> String {
103 let ($($tp_name,)+) = &self.0;
104 let mut message = String::new();
105 $(
106 message.push_str(&$tp_name.message(expression, actual, inverted, format));
107 )+
108 message
109 }
110 }
111 };
112}
113
114impl_expectation_for_all_combinator! { A1 }
115impl_expectation_for_all_combinator! { A1 A2 }
116impl_expectation_for_all_combinator! { A1 A2 A3 }
117impl_expectation_for_all_combinator! { A1 A2 A3 A4 }
118impl_expectation_for_all_combinator! { A1 A2 A3 A4 A5 }
119impl_expectation_for_all_combinator! { A1 A2 A3 A4 A5 A6 }
120impl_expectation_for_all_combinator! { A1 A2 A3 A4 A5 A6 A7 }
121impl_expectation_for_all_combinator! { A1 A2 A3 A4 A5 A6 A7 A8 }
122impl_expectation_for_all_combinator! { A1 A2 A3 A4 A5 A6 A7 A8 A9 }
123impl_expectation_for_all_combinator! { A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 }
124impl_expectation_for_all_combinator! { A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 }
125impl_expectation_for_all_combinator! { A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 }
126
127macro_rules! impl_expectation_for_any_combinator {
128 ( $( $tp_name:ident )+ ) => {
129 #[allow(non_snake_case)]
130 impl<S, $($tp_name: Expectation<S>),+> Expectation<S> for Any<($(Rec<$tp_name>,)+)> {
131 fn test(&mut self, subject: &S) -> bool {
132 let ($($tp_name,)+) = &mut self.0;
133 $(
134 let $tp_name = $tp_name.test(subject);
135 )+
136 $( $tp_name )||+
137 }
138
139 fn message(
140 &self,
141 expression: &Expression<'_>,
142 actual: &S,
143 inverted: bool,
144 format: &DiffFormat,
145 ) -> String {
146 let ($($tp_name,)+) = &self.0;
147 let mut message = String::new();
148 $(
149 message.push_str(&$tp_name.message(expression, actual, inverted, format));
150 )+
151 message
152 }
153 }
154 };
155}
156
157impl_expectation_for_any_combinator! { A1 }
158impl_expectation_for_any_combinator! { A1 A2 }
159impl_expectation_for_any_combinator! { A1 A2 A3 }
160impl_expectation_for_any_combinator! { A1 A2 A3 A4 }
161impl_expectation_for_any_combinator! { A1 A2 A3 A4 A5 }
162impl_expectation_for_any_combinator! { A1 A2 A3 A4 A5 A6 }
163impl_expectation_for_any_combinator! { A1 A2 A3 A4 A5 A6 A7 }
164impl_expectation_for_any_combinator! { A1 A2 A3 A4 A5 A6 A7 A8 }
165impl_expectation_for_any_combinator! { A1 A2 A3 A4 A5 A6 A7 A8 A9 }
166impl_expectation_for_any_combinator! { A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 }
167impl_expectation_for_any_combinator! { A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 }
168impl_expectation_for_any_combinator! { A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 }
169
170#[cfg(test)]
171mod tests;