| 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::fmt::{Debug, Formatter}; |
| 13 | use crate::marker::PhantomData; |
| 14 | |
| 15 | // ***** TryCapture - Generic ***** |
| 16 | |
| 17 | /// Marker used by [Capture] |
| 18 | #[unstable (feature = "generic_assert_internals" , issue = "44838" )] |
| 19 | pub struct TryCaptureWithoutDebug; |
| 20 | |
| 21 | /// Catches an arbitrary `E` and modifies `to` accordingly |
| 22 | #[unstable (feature = "generic_assert_internals" , issue = "44838" )] |
| 23 | pub 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 | |
| 28 | impl<E> TryCaptureGeneric<E, TryCaptureWithoutDebug> for &Wrapper<&E> { |
| 29 | #[inline ] |
| 30 | fn try_capture(&self, _: &mut Capture<E, TryCaptureWithoutDebug>) {} |
| 31 | } |
| 32 | |
| 33 | impl<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" )] |
| 43 | pub struct TryCaptureWithDebug; |
| 44 | |
| 45 | /// Catches an arbitrary `E: Printable` and modifies `to` accordingly |
| 46 | #[unstable (feature = "generic_assert_internals" , issue = "44838" )] |
| 47 | pub 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 | |
| 52 | impl<E> TryCapturePrintable<E, TryCaptureWithDebug> for Wrapper<&E> |
| 53 | where |
| 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 | |
| 62 | impl<E> Debug for Capture<E, TryCaptureWithDebug> |
| 63 | where |
| 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" )] |
| 83 | pub 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 | |
| 92 | impl<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" )] |
| 101 | pub struct Wrapper<T>(pub T); |
| 102 | |
| 103 | /// Tells which elements can be copied and displayed |
| 104 | #[unstable (feature = "generic_assert_internals" , issue = "44838" )] |
| 105 | pub trait Printable: Copy + Debug {} |
| 106 | |
| 107 | impl<T> Printable for T where T: Copy + Debug {} |
| 108 | |