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(data:"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(data:"N/A"),
69 Some(ref value: &E) => Debug::fmt(self: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 {}
108

Provided by KDAB

Privacy Policy
Learn Rust with the experts
Find out more