Skip to main content

googletest/matcher_support/
auto_eq.rs

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]
27macro_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
45pub mod internal {
46    use crate::{
47        matcher::MatcherBase,
48        matchers::{eq, EqMatcher},
49    };
50
51    pub struct Wrapper<T>(pub T);
52
53    impl<T: MatcherBase> Wrapper<&'_ T> {
54        #[inline]
55        pub fn kind(&self) -> MatcherTag {
56            MatcherTag
57        }
58    }
59
60    pub trait ExpectedKind {
61        #[inline]
62        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]
73        pub fn matcher<M>(self, matcher: M) -> M {
74            matcher
75        }
76    }
77    pub struct ExpectedTag;
78
79    impl ExpectedTag {
80        #[inline]
81        pub fn matcher<T>(self, expected: T) -> EqMatcher<T> {
82            eq(expected)
83        }
84    }
85}
86
87#[cfg(test)]
88mod tests {
89    use crate::prelude::*;
90    use crate::Result;
91
92    #[test]
93    fn auto_ref_matcher() -> Result<()> {
94        verify_that!(123, __auto_eq!(ge(9)))
95    }
96
97    #[test]
98    fn auto_ref_expected() -> Result<()> {
99        verify_that!(123, __auto_eq!(123))
100    }
101
102    #[test]
103    fn auto_ref_on_ref_matcher() -> Result<()> {
104        let matcher = eq(123);
105        verify_that!(123, __auto_eq!(&matcher))
106    }
107}