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::{
13 fmt::{Debug, Formatter},
14 marker::PhantomData,
15};
16
17// ***** TryCapture - Generic *****
18
19/// Marker used by [Capture]
20#[unstable(feature = "generic_assert_internals", issue = "44838")]
21pub struct TryCaptureWithoutDebug;
22
23/// Catches an arbitrary `E` and modifies `to` accordingly
24#[unstable(feature = "generic_assert_internals", issue = "44838")]
25pub trait TryCaptureGeneric<E, M> {
26 /// Similar to [TryCapturePrintable] but generic to any `E`.
27 fn try_capture(&self, to: &mut Capture<E, M>);
28}
29
30impl<E> TryCaptureGeneric<E, TryCaptureWithoutDebug> for &Wrapper<&E> {
31 #[inline]
32 fn try_capture(&self, _: &mut Capture<E, TryCaptureWithoutDebug>) {}
33}
34
35impl<E> Debug for Capture<E, TryCaptureWithoutDebug> {
36 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> {
37 f.write_str(data:"N/A")
38 }
39}
40
41// ***** TryCapture - Printable *****
42
43/// Marker used by [Capture]
44#[unstable(feature = "generic_assert_internals", issue = "44838")]
45pub struct TryCaptureWithDebug;
46
47/// Catches an arbitrary `E: Printable` and modifies `to` accordingly
48#[unstable(feature = "generic_assert_internals", issue = "44838")]
49pub trait TryCapturePrintable<E, M> {
50 /// Similar as [TryCaptureGeneric] but specialized to any `E: Printable`.
51 fn try_capture(&self, to: &mut Capture<E, M>);
52}
53
54impl<E> TryCapturePrintable<E, TryCaptureWithDebug> for Wrapper<&E>
55where
56 E: Printable,
57{
58 #[inline]
59 fn try_capture(&self, to: &mut Capture<E, TryCaptureWithDebug>) {
60 to.elem = Some(*self.0);
61 }
62}
63
64impl<E> Debug for Capture<E, TryCaptureWithDebug>
65where
66 E: Printable,
67{
68 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> {
69 match self.elem {
70 None => f.write_str(data:"N/A"),
71 Some(ref value: &E) => Debug::fmt(self:value, f),
72 }
73 }
74}
75
76// ***** Others *****
77
78/// All possible captured `assert!` elements
79///
80/// # Types
81///
82/// * `E`: **E**lement that is going to be displayed.
83/// * `M`: **M**arker used to differentiate [Capture]s in regards to [Debug].
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 {}
110