1#![no_std]
2use core::fmt::Debug;
14#[cfg(not(debug_assertions))]
15use core::marker::PhantomData;
16
17#[repr(transparent)]
18pub struct DebugValue<T>(
19 #[cfg(debug_assertions)] T,
20 #[cfg(not(debug_assertions))] PhantomData<T>,
21);
22
23macro_rules! if_else {
24 ($a:expr,$b:expr) => {{
25 #[cfg(debug_assertions)]
26 {
27 $a
28 }
29 #[cfg(not(debug_assertions))]
30 {
31 $b
32 }
33 }};
34 ($a:expr) => {
35 if_else! { $a,PhantomData }
36 };
37}
38
39#[cfg_attr(not(debug_assertions), allow(unused_variables))]
40impl<T> DebugValue<T> {
41 pub fn new_cloned(x: &T) -> Self
42 where
43 T: Clone,
44 {
45 Self(if_else!(x.clone()))
46 }
47
48 #[inline]
49 pub fn new_with(f: impl FnOnce() -> T) -> Self {
50 Self(if_else!(f()))
51 }
52
53 #[inline]
54 pub fn new(x: T) -> Self {
55 Self(if_else!(x))
56 }
57
58 #[inline]
59 pub fn map<R>(self, f: impl FnOnce(T) -> R) -> DebugValue<R> {
60 DebugValue(if_else!(f(self.0)))
61 }
62
63 #[inline]
64 pub fn zip<U>(self, other: DebugValue<U>) -> DebugValue<(T, U)> {
65 DebugValue(if_else!((self.0, other.0)))
66 }
67
68 #[inline]
69 pub fn as_ref(&self) -> DebugValue<&T> {
70 DebugValue(if_else!(&self.0))
71 }
72
73 #[inline]
74 pub fn as_mut(&mut self) -> DebugValue<&mut T> {
75 DebugValue(if_else!(&mut self.0))
76 }
77
78 #[inline]
79 pub fn assert_eq(&self, other: &T)
80 where
81 T: Debug + PartialEq,
82 {
83 #[cfg(debug_assertions)]
84 {
85 assert_eq!(&self.0, other)
86 }
87 }
88
89 #[inline]
90 pub fn into_option(self) -> Option<T> {
91 if_else!(Some(self.0), None)
92 }
93
94 #[inline]
95 pub fn from_option(x: Option<T>) -> Self {
96 DebugValue(if_else!(x.unwrap(), PhantomData))
97 }
98
99 #[inline]
100 pub fn try_from_option(x: Option<T>) -> Option<Self> {
101 Some(DebugValue(if_else!(x?, PhantomData)))
102 }
103}