core/
asserting.rs

1// Contains the machinery necessary to print useful `assert!` messages. Not intended for public
2// usage, not even nightly use-cases.
3//
4// Based on https://github.com/dtolnay/case-studies/tree/master/autoref-specialization. When
5// 'specialization' is robust enough (5 years? 10 years? Never?), `Capture` can be specialized
6// to [Printable].
7
8#![allow(missing_debug_implementations)]
9#![doc(hidden)]
10#![unstable(feature = "generic_assert_internals", issue = "44838")]
11
12use crate::fmt::{Debug, Formatter};
13use crate::marker::PhantomData;
14
15// ***** TryCapture - Generic *****
16
17/// Marker used by [Capture]
18#[unstable(feature = "generic_assert_internals", issue = "44838")]
19pub struct TryCaptureWithoutDebug;
20
21/// Catches an arbitrary `E` and modifies `to` accordingly
22#[unstable(feature = "generic_assert_internals", issue = "44838")]
23pub trait TryCaptureGeneric<E, M> {
24    /// Similar to [TryCapturePrintable] but generic to any `E`.
25    fn try_capture(&self, to: &mut Capture<E, M>);
26}
27
28impl<E> TryCaptureGeneric<E, TryCaptureWithoutDebug> for &Wrapper<&E> {
29    #[inline]
30    fn try_capture(&self, _: &mut Capture<E, TryCaptureWithoutDebug>) {}
31}
32
33impl<E> Debug for Capture<E, TryCaptureWithoutDebug> {
34    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> {
35        f.write_str("N/A")
36    }
37}
38
39// ***** TryCapture - Printable *****
40
41/// Marker used by [Capture]
42#[unstable(feature = "generic_assert_internals", issue = "44838")]
43pub struct TryCaptureWithDebug;
44
45/// Catches an arbitrary `E: Printable` and modifies `to` accordingly
46#[unstable(feature = "generic_assert_internals", issue = "44838")]
47pub trait TryCapturePrintable<E, M> {
48    /// Similar as [TryCaptureGeneric] but specialized to any `E: Printable`.
49    fn try_capture(&self, to: &mut Capture<E, M>);
50}
51
52impl<E> TryCapturePrintable<E, TryCaptureWithDebug> for Wrapper<&E>
53where
54    E: Printable,
55{
56    #[inline]
57    fn try_capture(&self, to: &mut Capture<E, TryCaptureWithDebug>) {
58        to.elem = Some(*self.0);
59    }
60}
61
62impl<E> Debug for Capture<E, TryCaptureWithDebug>
63where
64    E: Printable,
65{
66    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> {
67        match self.elem {
68            None => f.write_str("N/A"),
69            Some(ref value) => Debug::fmt(value, f),
70        }
71    }
72}
73
74// ***** Others *****
75
76//spellchecker:off
77/// All possible captured `assert!` elements
78///
79/// # Types
80///
81/// * `E`: **E**lement that is going to be displayed.
82/// * `M`: **M**arker used to differentiate [Capture]s in regards to [Debug].
83//spellchecker:on
84#[unstable(feature = "generic_assert_internals", issue = "44838")]
85pub struct Capture<E, M> {
86    // If None, then `E` does not implements [Printable] or `E` wasn't evaluated (`assert!( ... )`
87    // short-circuited).
88    //
89    // If Some, then `E` implements [Printable] and was evaluated.
90    pub elem: Option<E>,
91    phantom: PhantomData<M>,
92}
93
94impl<M, T> Capture<M, T> {
95    #[inline]
96    pub const fn new() -> Self {
97        Self { elem: None, phantom: PhantomData }
98    }
99}
100
101/// Necessary for the implementations of `TryCapture*`
102#[unstable(feature = "generic_assert_internals", issue = "44838")]
103pub struct Wrapper<T>(pub T);
104
105/// Tells which elements can be copied and displayed
106#[unstable(feature = "generic_assert_internals", issue = "44838")]
107pub trait Printable: Copy + Debug {}
108
109impl<T> Printable for T where T: Copy + Debug {}