bevy_utils/
debug_info.rs

1use crate::cfg;
2cfg::alloc! {
3    use alloc::{borrow::Cow, fmt, string::String};
4}
5#[cfg(feature = "debug")]
6use core::any::type_name;
7use core::ops::Deref;
8use disqualified::ShortName;
9
10#[cfg(not(feature = "debug"))]
11const FEATURE_DISABLED: &str = "Enable the debug feature to see the name";
12
13/// Wrapper to help debugging ECS issues. This is used to display the names of systems, components, ...
14///
15/// * If the `debug` feature is enabled, the actual name will be used
16/// * If it is disabled, a string mentioning the disabled feature will be used
17#[derive(Clone, PartialEq, Eq)]
18pub struct DebugName {
19    #[cfg(feature = "debug")]
20    name: Cow<'static, str>,
21}
22
23cfg::alloc! {
24    impl fmt::Display for DebugName {
25        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
26            // Deref to `str`, which will use `FEATURE_DISABLED` if necessary
27            write!(f, "{}", &**self)
28        }
29    }
30
31    impl fmt::Debug for DebugName {
32        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
33            // Deref to `str`, which will use `FEATURE_DISABLED` if necessary
34            write!(f, "{:?}", &**self)
35        }
36    }
37}
38
39impl DebugName {
40    /// Create a new `DebugName` from a `&str`
41    ///
42    /// The value will be ignored if the `debug` feature is not enabled
43    #[cfg_attr(
44        not(feature = "debug"),
45        expect(
46            unused_variables,
47            reason = "The value will be ignored if the `debug` feature is not enabled"
48        )
49    )]
50    pub const fn borrowed(value: &'static str) -> Self {
51        DebugName {
52            #[cfg(feature = "debug")]
53            name: Cow::Borrowed(value),
54        }
55    }
56
57    cfg::alloc! {
58        /// Create a new `DebugName` from a `String`
59        ///
60        /// The value will be ignored if the `debug` feature is not enabled
61        #[cfg_attr(
62            not(feature = "debug"),
63            expect(
64                unused_variables,
65                reason = "The value will be ignored if the `debug` feature is not enabled"
66            )
67        )]
68        pub fn owned(value: String) -> Self {
69            DebugName {
70                #[cfg(feature = "debug")]
71                name: Cow::Owned(value),
72            }
73        }
74    }
75
76    /// Create a new `DebugName` from a type by using its [`core::any::type_name`]
77    ///
78    /// The value will be ignored if the `debug` feature is not enabled
79    pub fn type_name<T>() -> Self {
80        DebugName {
81            #[cfg(feature = "debug")]
82            name: Cow::Borrowed(type_name::<T>()),
83        }
84    }
85
86    /// Get the [`ShortName`] corresponding to this debug name
87    ///
88    /// The value will be a static string if the `debug` feature is not enabled
89    pub fn shortname(&self) -> ShortName<'_> {
90        #[cfg(feature = "debug")]
91        return ShortName(self.name.as_ref());
92        #[cfg(not(feature = "debug"))]
93        return ShortName(FEATURE_DISABLED);
94    }
95
96    /// Return the string hold by this `DebugName`
97    ///
98    /// This is intended for debugging purpose, and only available if the `debug` feature is enabled
99    #[cfg(feature = "debug")]
100    pub fn as_string(&self) -> String {
101        self.name.clone().into_owned()
102    }
103}
104
105impl Deref for DebugName {
106    type Target = str;
107
108    fn deref(&self) -> &Self::Target {
109        #[cfg(feature = "debug")]
110        return &self.name;
111        #[cfg(not(feature = "debug"))]
112        return FEATURE_DISABLED;
113    }
114}
115
116cfg::alloc! {
117    impl From<Cow<'static, str>> for DebugName {
118        #[cfg_attr(
119            not(feature = "debug"),
120            expect(
121                unused_variables,
122                reason = "The value will be ignored if the `debug` feature is not enabled"
123            )
124        )]
125        fn from(value: Cow<'static, str>) -> Self {
126            Self {
127                #[cfg(feature = "debug")]
128                name: value,
129            }
130        }
131    }
132
133    impl From<String> for DebugName {
134        fn from(value: String) -> Self {
135            Self::owned(value)
136        }
137    }
138
139    impl From<DebugName> for Cow<'static, str> {
140        #[cfg_attr(
141            not(feature = "debug"),
142            expect(
143                unused_variables,
144                reason = "The value will be ignored if the `debug` feature is not enabled"
145            )
146        )]
147        fn from(value: DebugName) -> Self {
148            #[cfg(feature = "debug")]
149            {
150                value.name
151            }
152            #[cfg(not(feature = "debug"))]
153            {
154                Cow::Borrowed(FEATURE_DISABLED)
155            }
156        }
157    }
158}
159
160impl From<&'static str> for DebugName {
161    fn from(value: &'static str) -> Self {
162        Self::borrowed(value)
163    }
164}