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 | |
12 | use 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" )] |
21 | pub struct TryCaptureWithoutDebug; |
22 | |
23 | /// Catches an arbitrary `E` and modifies `to` accordingly |
24 | #[unstable (feature = "generic_assert_internals" , issue = "44838" )] |
25 | pub 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 | |
30 | impl<E> TryCaptureGeneric<E, TryCaptureWithoutDebug> for &Wrapper<&E> { |
31 | #[inline ] |
32 | fn try_capture(&self, _: &mut Capture<E, TryCaptureWithoutDebug>) {} |
33 | } |
34 | |
35 | impl<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" )] |
45 | pub struct TryCaptureWithDebug; |
46 | |
47 | /// Catches an arbitrary `E: Printable` and modifies `to` accordingly |
48 | #[unstable (feature = "generic_assert_internals" , issue = "44838" )] |
49 | pub 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 | |
54 | impl<E> TryCapturePrintable<E, TryCaptureWithDebug> for Wrapper<&E> |
55 | where |
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 | |
64 | impl<E> Debug for Capture<E, TryCaptureWithDebug> |
65 | where |
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" )] |
85 | pub 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 | |
94 | impl<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" )] |
103 | pub struct Wrapper<T>(pub T); |
104 | |
105 | /// Tells which elements can be copied and displayed |
106 | #[unstable (feature = "generic_assert_internals" , issue = "44838" )] |
107 | pub trait Printable: Copy + Debug {} |
108 | |
109 | impl<T> Printable for T where T: Copy + Debug {} |
110 | |