• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #![doc(hidden)]
16 
17 /// Macro that wraps the expression with `eq(...)` if the expression is
18 /// not a matcher.
19 ///
20 /// This is useful to let users pass expected value to macro matchers like
21 /// `field!` and `property!`.
22 ///`
23 /// **For internal use only. API stablility is not guaranteed!**
24 /// If you are interested in using it in your matcher, please file an issue to
25 /// stabilize this.
26 #[macro_export]
27 macro_rules! __auto_eq {
28     ($e:expr) => {{
29         #[allow(unused_imports)]
30         use $crate::matcher_support::__internal_unstable_do_not_depend_on_these::ExpectedKind as _;
31         match $e {
32             expected => {
33                 $crate::matcher_support::__internal_unstable_do_not_depend_on_these::Wrapper(
34                     &expected,
35                 )
36                 .kind()
37                 .matcher(expected)
38             }
39         }
40     }};
41 }
42 
43 // This reimplements the pattern presented in
44 // https://github.com/dtolnay/case-studies/issues/14
45 pub mod internal {
46     use crate::{
47         matcher::MatcherBase,
48         matchers::{eq, EqMatcher},
49     };
50 
51     pub struct Wrapper<T>(pub T);
52 
53     impl<'a, T: MatcherBase> Wrapper<&'a T> {
54         #[inline]
kind(&self) -> MatcherTag55         pub fn kind(&self) -> MatcherTag {
56             MatcherTag
57         }
58     }
59 
60     pub trait ExpectedKind {
61         #[inline]
kind(&self) -> ExpectedTag62         fn kind(&self) -> ExpectedTag {
63             ExpectedTag
64         }
65     }
66 
67     impl<T> ExpectedKind for Wrapper<T> {}
68 
69     pub struct MatcherTag;
70 
71     impl MatcherTag {
72         #[inline]
matcher<M>(self, matcher: M) -> M73         pub fn matcher<M>(self, matcher: M) -> M {
74             matcher
75         }
76     }
77     pub struct ExpectedTag;
78 
79     impl ExpectedTag {
80         #[inline]
matcher<T>(self, expected: T) -> EqMatcher<T>81         pub fn matcher<T>(self, expected: T) -> EqMatcher<T> {
82             eq(expected)
83         }
84     }
85 }
86 
87 #[cfg(test)]
88 mod tests {
89     use crate::prelude::*;
90 
91     #[test]
auto_ref_matcher() -> Result<()>92     fn auto_ref_matcher() -> Result<()> {
93         verify_that!(123, __auto_eq!(ge(9)))
94     }
95 
96     #[test]
auto_ref_expected() -> Result<()>97     fn auto_ref_expected() -> Result<()> {
98         verify_that!(123, __auto_eq!(123))
99     }
100 
101     #[test]
auto_ref_on_ref_matcher() -> Result<()>102     fn auto_ref_on_ref_matcher() -> Result<()> {
103         let matcher = eq(123);
104         verify_that!(123, __auto_eq!(&matcher))
105     }
106 }
107