open_coroutine_core/common/
macros.rs1#[allow(unused_macros)]
5#[macro_export]
6macro_rules! trace {
7 ($( $args:expr ),*) => {
8 #[cfg(all(debug_assertions, feature = "log"))]
9 tracing::trace!( $( $args ),* );
10 }
11}
12
13#[allow(unused_macros)]
15#[macro_export]
16macro_rules! info {
17 ($( $args:expr ),*) => {
18 #[cfg(feature = "log")]
19 tracing::info!( $( $args ),* );
20 }
21}
22
23#[allow(unused_macros)]
25#[macro_export]
26macro_rules! warn {
27 ($( $args:expr ),*) => {
28 #[cfg(feature = "log")]
29 tracing::warn!( $( $args ),* );
30 }
31}
32
33#[allow(unused_macros)]
35#[macro_export]
36macro_rules! error {
37 ($( $args:expr ),*) => {
38 #[cfg(feature = "log")]
39 tracing::error!( $( $args ),* );
40 }
41}
42
43#[macro_export]
45macro_rules! catch {
46 ($f:expr, $msg:expr, $arg:expr) => {
47 std::panic::catch_unwind(std::panic::AssertUnwindSafe($f)).map_err(|e| {
48 let message = if let Some(msg) = e.downcast_ref::<&'static str>() {
49 *msg
50 } else {
51 $msg.leak()
52 };
53 $crate::error!("{} failed with error:{}", $arg, message);
54 message
55 })
56 };
57}
58
59#[allow(unused_macros)]
61#[macro_export]
62macro_rules! impl_display_by_debug {
63 ($struct_name:ident$(<$($generic1:tt $( : $trait_tt1: tt $( + $trait_tt2: tt)*)?),+>)?
64 $(where $(
65 $generic2:tt $( : $trait_tt3: tt $( + $trait_tt4: tt)*)?
66 ),+)?
67 ) => {
68 impl$(<$($generic1 $( : $trait_tt1 $( + $trait_tt2)*)?),+>)? std::fmt::Display
69 for $struct_name$(<$($generic1),+>)?
70 where
71 $struct_name$(<$($generic1),+>)?: std::fmt::Debug,
72 $($($generic2 $( : $trait_tt3 $( + $trait_tt4)*)?),+,)?
73 {
74 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75 std::fmt::Debug::fmt(self, f)
76 }
77 }
78 };
79}
80
81#[allow(unused_macros)]
84#[macro_export]
85macro_rules! impl_current_for {
86 (
87 $name:ident,
88 $struct_name:ident$(<$($generic:tt $( : $trait_tt1: tt $( + $trait_tt2: tt)*)?),+>)?
89 ) => {
90 thread_local! {
91 static $name: crossbeam_utils::atomic::AtomicCell<std::collections::VecDeque<*const std::ffi::c_void>> =
92 const { crossbeam_utils::atomic::AtomicCell::new(std::collections::VecDeque::new()) };
93 }
94
95 impl$(<$($generic $( : $trait_tt1 $( + $trait_tt2)*)?),+>)? $struct_name$(<$($generic),+>)? {
96 pub(crate) fn init_current(current: &Self) {
98 $name.with(|s| unsafe {
99 s.as_ptr()
100 .as_mut()
101 .unwrap_or_else(|| {
102 panic!(
103 "thread:{} init {} current failed",
104 std::thread::current().name().unwrap_or("unknown"),
105 stringify!($name)
106 )
107 })
108 .push_front(core::ptr::from_ref(current).cast::<std::ffi::c_void>());
109 });
110 }
111
112 #[must_use]
114 #[allow(unreachable_pub)]
115 pub fn current<'current>() -> Option<&'current Self> {
116 $name.with(|s| unsafe {
117 s.as_ptr()
118 .as_ref()
119 .unwrap_or_else(|| {
120 panic!(
121 "thread:{} get {} current failed",
122 std::thread::current().name().unwrap_or("unknown"),
123 stringify!($name)
124 )
125 })
126 .front()
127 .map(|ptr| &*(*ptr).cast::<Self>())
128 })
129 }
130
131 pub(crate) fn clean_current() {
133 $name.with(|s| unsafe {
134 _ = s.as_ptr()
135 .as_mut()
136 .unwrap_or_else(|| {
137 panic!(
138 "thread:{} clean {} current failed",
139 std::thread::current().name().unwrap_or("unknown"),
140 stringify!($name)
141 )
142 })
143 .pop_front();
144 });
145 }
146 }
147 };
148}
149
150#[macro_export]
153macro_rules! impl_for_named {
154 ($struct_name:ident$(<$($generic:tt $( : $trait_tt1: tt $( + $trait_tt2: tt)*)?),+>)?) => {
155 $crate::impl_ord_for_named!($struct_name$(<$($generic $( : $trait_tt1 $( + $trait_tt2)*)?),+>)?);
156 $crate::impl_hash_for_named!($struct_name$(<$($generic $( : $trait_tt1 $( + $trait_tt2)*)?),+>)?);
157 };
158}
159
160#[macro_export]
162macro_rules! impl_eq_for_named {
163 ($struct_name:ident$(<$($generic:tt $( : $trait_tt1: tt $( + $trait_tt2: tt)*)?),+>)?) => {
164 impl$(<$($generic $( : $trait_tt1 $( + $trait_tt2)*)?),+>)? PartialEq<Self>
165 for $struct_name$(<$($generic),+>)?
166 {
167 fn eq(&self, other: &Self) -> bool {
168 self.name().eq(other.name())
169 }
170 }
171
172 impl$(<$($generic $( : $trait_tt1 $( + $trait_tt2)*)?),+>)? Eq
173 for $struct_name$(<$($generic),+>)?
174 {
175 }
176 };
177}
178
179#[macro_export]
181macro_rules! impl_ord_for_named {
182 ($struct_name:ident$(<$($generic:tt $( : $trait_tt1: tt $( + $trait_tt2: tt)*)?),+>)?) => {
183 $crate::impl_eq_for_named!($struct_name$(<$($generic $( : $trait_tt1 $( + $trait_tt2)*)?),+>)?);
184
185 impl$(<$($generic $( : $trait_tt1 $( + $trait_tt2)*)?),+>)? PartialOrd<Self>
186 for $struct_name$(<$($generic),+>)?
187 {
188 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
189 Some(self.cmp(other))
190 }
191 }
192
193 impl$(<$($generic $( : $trait_tt1 $( + $trait_tt2)*)?),+>)? Ord
194 for $struct_name$(<$($generic),+>)?
195 {
196 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
197 self.name().cmp(other.name())
198 }
199 }
200 }
201}
202
203#[macro_export]
205macro_rules! impl_hash_for_named {
206 ($struct_name:ident$(<$($generic:tt $( : $trait_tt1: tt $( + $trait_tt2: tt)*)?),+>)?) => {
207 impl$(<$($generic $( : $trait_tt1 $( + $trait_tt2)*)?),+>)? std::hash::Hash
208 for $struct_name$(<$($generic),+>)?
209 {
210 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
211 self.name().hash(state)
212 }
213 }
214 }
215}