1 // Copyright 2023 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 use crate::{
18 description::Description,
19 matcher::{Matcher, MatcherResult},
20 };
21 use std::{fmt::Debug, marker::PhantomData};
22
23 /// Matches precisely values matched by `inner`.
24 ///
25 /// The returned matcher produces a description prefixed by the string
26 /// `description`. This is useful in contexts where the test assertion failure
27 /// output must include the additional description.
is<'a, ActualT: Debug + 'a, InnerMatcherT: Matcher<ActualT = ActualT> + 'a>( description: &'a str, inner: InnerMatcherT, ) -> impl Matcher<ActualT = ActualT> + 'a28 pub fn is<'a, ActualT: Debug + 'a, InnerMatcherT: Matcher<ActualT = ActualT> + 'a>(
29 description: &'a str,
30 inner: InnerMatcherT,
31 ) -> impl Matcher<ActualT = ActualT> + 'a {
32 IsMatcher { description, inner, phantom: Default::default() }
33 }
34
35 struct IsMatcher<'a, ActualT, InnerMatcherT> {
36 description: &'a str,
37 inner: InnerMatcherT,
38 phantom: PhantomData<ActualT>,
39 }
40
41 impl<'a, ActualT: Debug, InnerMatcherT: Matcher<ActualT = ActualT>> Matcher
42 for IsMatcher<'a, ActualT, InnerMatcherT>
43 {
44 type ActualT = ActualT;
45
matches(&self, actual: &Self::ActualT) -> MatcherResult46 fn matches(&self, actual: &Self::ActualT) -> MatcherResult {
47 self.inner.matches(actual)
48 }
49
describe(&self, matcher_result: MatcherResult) -> Description50 fn describe(&self, matcher_result: MatcherResult) -> Description {
51 match matcher_result {
52 MatcherResult::Match => format!(
53 "is {} which {}",
54 self.description,
55 self.inner.describe(MatcherResult::Match)
56 )
57 .into(),
58 MatcherResult::NoMatch => format!(
59 "is not {} which {}",
60 self.description,
61 self.inner.describe(MatcherResult::Match)
62 )
63 .into(),
64 }
65 }
66
explain_match(&self, actual: &Self::ActualT) -> Description67 fn explain_match(&self, actual: &Self::ActualT) -> Description {
68 self.inner.explain_match(actual)
69 }
70 }
71