alt_failure/backtrace/mod.rs
1use core::fmt::{self, Debug, Display};
2
3macro_rules! with_backtrace { ($($i:item)*) => ($(#[cfg(all(feature = "backtrace", feature = "std"))]$i)*) }
4macro_rules! without_backtrace { ($($i:item)*) => ($(#[cfg(not(all(feature = "backtrace", feature = "std")))]$i)*) }
5
6without_backtrace! {
7 /// A `Backtrace`.
8 ///
9 /// This is an opaque wrapper around the backtrace provided by
10 /// libbacktrace. A variety of optimizations have been performed to avoid
11 /// unnecessary or ill-advised work:
12 ///
13 /// - If this crate is compiled in `no_std` compatible mode, `Backtrace`
14 /// is an empty struct, and will be completely compiled away.
15 /// - If this crate is run without the `RUST_BACKTRACE` environmental
16 /// variable enabled, the backtrace will not be generated at runtime.
17 /// - Even if a backtrace is generated, the most expensive part of
18 /// generating a backtrace is symbol resolution. This backtrace does not
19 /// perform symbol resolution until it is actually read (e.g. by
20 /// printing it). If the Backtrace is never used for anything, symbols
21 /// never get resolved.
22 ///
23 /// Even with these optimizations, including a backtrace in your failure
24 /// may not be appropriate to your use case. You are not required to put a
25 /// backtrace in a custom `Fail` type.
26 ///
27 /// > (We have detected that this crate was documented with no_std
28 /// > compatibility turned on. The version of this crate that has been
29 /// > documented here will never generate a backtrace.)
30 pub struct Backtrace {
31 _secret: (),
32 }
33
34 impl Backtrace {
35 /// Constructs a new backtrace. This will only create a real backtrace
36 /// if the crate is compiled in std mode and the `RUST_BACKTRACE`
37 /// environmental variable is activated.
38 ///
39 /// > (We have detected that this crate was documented with no_std
40 /// > compatibility turned on. The version of this crate that has been
41 /// > documented here will never generate a backtrace.)
42 pub fn new() -> Backtrace {
43 Backtrace { _secret: () }
44 }
45
46 #[cfg(feature = "std")]
47 pub(crate) fn none() -> Backtrace {
48 Backtrace { _secret: () }
49 }
50
51 #[cfg(feature = "std")]
52 pub(crate) fn is_none(&self) -> bool {
53 true
54 }
55
56 /// Returns true if displaying this backtrace would be an empty string.
57 ///
58 /// > (We have detected that this crate was documented with no_std
59 /// > compatibility turned on. The version of this crate that has been
60 /// > documented here will never generate a backtrace and this method
61 /// > will always return true.)
62 pub fn is_empty(&self) -> bool {
63 true
64 }
65 }
66
67 impl Default for Backtrace {
68 fn default() -> Backtrace {
69 Backtrace::new()
70 }
71 }
72
73 impl Debug for Backtrace {
74 fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
75 Ok(())
76 }
77 }
78
79 impl Display for Backtrace {
80 fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
81 Ok(())
82 }
83 }
84}
85
86with_backtrace! {
87 extern crate backtrace;
88
89 mod internal;
90
91 use self::internal::InternalBacktrace;
92
93 /// A `Backtrace`.
94 ///
95 /// This is an opaque wrapper around the backtrace provided by
96 /// libbacktrace. A variety of optimizations have been performed to avoid
97 /// unnecessary or ill-advised work:
98 ///
99 /// - If this crate is compiled in `no_std` compatible mode, `Backtrace`
100 /// is an empty struct, and will be completely compiled away.
101 /// - If this crate is run without the `RUST_BACKTRACE` environmental
102 /// variable enabled, the backtrace will not be generated at runtime.
103 /// - Even if a backtrace is generated, the most expensive part of
104 /// generating a backtrace is symbol resolution. This backtrace does not
105 /// perform symbol resolution until it is actually read (e.g. by
106 /// printing it). If the Backtrace is never used for anything, symbols
107 /// never get resolved.
108 ///
109 /// Even with these optimizations, including a backtrace in your failure
110 /// may not be appropriate to your use case. You are not required to put a
111 /// backtrace in a custom `Fail` type.
112 pub struct Backtrace {
113 internal: InternalBacktrace
114 }
115
116 impl Backtrace {
117 /// Constructs a new backtrace. This will only create a real backtrace
118 /// if the crate is compiled in std mode and the `RUST_BACKTRACE`
119 /// environmental variable is activated.
120 pub fn new() -> Backtrace {
121 Backtrace { internal: InternalBacktrace::new() }
122 }
123
124 pub(crate) fn none() -> Backtrace {
125 Backtrace { internal: InternalBacktrace::none() }
126 }
127
128 pub(crate) fn is_none(&self) -> bool {
129 self.internal.is_none()
130 }
131
132 /// Returns true if displaying this backtrace would be an empty string.
133 pub fn is_empty(&self) -> bool {
134 self.internal.is_none()
135 }
136 }
137
138 impl Default for Backtrace {
139 fn default() -> Backtrace {
140 Backtrace::new()
141 }
142 }
143
144 impl Debug for Backtrace {
145 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
146 if let Some(bt) = self.internal.as_backtrace() {
147 Debug::fmt(bt, f)
148 } else { Ok(()) }
149 }
150 }
151
152 impl Display for Backtrace {
153 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
154 if let Some(bt) = self.internal.as_backtrace() {
155 Debug::fmt(bt, f)
156 } else { Ok(()) }
157 }
158 }
159}