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/// All possible captured `assert!` elements
77///
78/// # Types
79///
80/// * `E`: **E**lement that is going to be displayed.
81/// * `M`: **M**arker used to differentiate [Capture]s in regards to [Debug].
82#[unstable(feature = "generic_assert_internals", issue = "44838")]
83pub struct Capture<E, M> {
84    // If None, then `E` does not implements [Printable] or `E` wasn't evaluated (`assert!( ... )`
85    // short-circuited).
86    //
87    // If Some, then `E` implements [Printable] and was evaluated.
88    pub elem: Option<E>,
89    phantom: PhantomData<M>,
90}
91
92impl<M, T> Capture<M, T> {
93    #[inline]
94    pub const fn new() -> Self {
95        Self { elem: None, phantom: PhantomData }
96    }
97}
98
99/// Necessary for the implementations of `TryCapture*`
100#[unstable(feature = "generic_assert_internals", issue = "44838")]
101pub struct Wrapper<T>(pub T);
102
103/// Tells which elements can be copied and displayed
104#[unstable(feature = "generic_assert_internals", issue = "44838")]
105pub trait Printable: Copy + Debug {}
106
107impl<T> Printable for T where T: Copy + Debug {}