Skip to main content

googletest/
fmt.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/// Functions for use only by the procedural macros in this module.
16///
17/// **For internal use only. API stablility is not guaranteed!**
18#[doc(hidden)]
19pub mod internal {
20    use std::fmt::{Debug, Write};
21
22    /// Wrapper to allow for inherent-method specialization based on whether a
23    /// type implements `Debug`.
24    pub struct FormatWrapper<'a, T: ?Sized>(pub &'a T);
25
26    /// Default implementation to render values that implement `Debug`.
27    ///
28    /// Used for autoref specialization to conditionally
29    /// render only values that implement `Debug`. See also
30    /// [`FormatNonDebugFallback`].
31    impl<T: Debug + ?Sized> FormatWrapper<'_, T> {
32        #[track_caller]
33        pub fn __googletest_write_expr_value(&self, output: &mut dyn Write, expr_label: &str) {
34            write!(output, "\n  {} = {:?},", expr_label, self.0)
35                .expect("Formatting to String should never fail");
36        }
37    }
38
39    /// Fallback implementation for rendering values for non-`Debug` types..
40    ///
41    /// Used for inherent-method specialization to conditionally render only
42    /// values that implement `Debug`. See also the specialized inherent impl on
43    /// [`FormatWrapper`] above.
44    pub trait FormatNonDebugFallback {
45        fn __googletest_write_expr_value(&self, output: &mut dyn Write, expr_label: &str);
46    }
47
48    impl<T: ?Sized> FormatNonDebugFallback for FormatWrapper<'_, T> {
49        #[track_caller]
50        fn __googletest_write_expr_value(&self, output: &mut dyn Write, expr_label: &str) {
51            write!(output, "\n  {expr_label} does not implement Debug,")
52                .expect("Formatting to String should never fail");
53        }
54    }
55
56    #[macro_export]
57    macro_rules! __googletest__write_expr_value(
58        ($output:expr, $expr_str:expr, $value:expr $(,)?) => {
59            {
60                use $crate::fmt::internal::FormatNonDebugFallback as _;
61                $crate::fmt::internal::FormatWrapper(&$value)
62                    .__googletest_write_expr_value(&mut $output, $expr_str)
63            }
64        }
65    );
66    pub use __googletest__write_expr_value;
67}