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`. try_capture(&self, to: &mut Capture<E, M>)27 fn try_capture(&self, to: &mut Capture<E, M>); 28 } 29 30 impl<E> TryCaptureGeneric<E, TryCaptureWithoutDebug> for &Wrapper<&E> { 31 #[inline] try_capture(&self, _: &mut Capture<E, TryCaptureWithoutDebug>)32 fn try_capture(&self, _: &mut Capture<E, TryCaptureWithoutDebug>) {} 33 } 34 35 impl<E> Debug for Capture<E, TryCaptureWithoutDebug> { fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error>36 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> { 37 f.write_str("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`. try_capture(&self, to: &mut Capture<E, M>)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] try_capture(&self, to: &mut Capture<E, TryCaptureWithDebug>)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 { fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error>68 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> { 69 match self.elem { 70 None => f.write_str("N/A"), 71 Some(ref value) => Debug::fmt(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] new() -> Self96 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