1use std::sync::atomic::{AtomicBool, Ordering};
2
3pub struct OnceFlag(AtomicBool);
6
7impl OnceFlag {
8 pub const fn new() -> Self {
10 Self(AtomicBool::new(true))
11 }
12
13 pub fn set(&self) -> bool {
15 self.0.swap(false, Ordering::Relaxed)
16 }
17}
18
19impl Default for OnceFlag {
20 fn default() -> Self {
21 Self::new()
22 }
23}
24
25#[macro_export]
27macro_rules! once {
28 ($expression:expr) => {{
29 static SHOULD_FIRE: $crate::OnceFlag = $crate::OnceFlag::new();
30 if SHOULD_FIRE.set() {
31 $expression;
32 }
33 }};
34}
35
36#[macro_export]
40macro_rules! trace_once {
41 ($($arg:tt)+) => ({
42 $crate::once!($crate::trace!($($arg)+))
43 });
44}
45
46#[macro_export]
50macro_rules! debug_once {
51 ($($arg:tt)+) => ({
52 $crate::once!($crate::debug!($($arg)+))
53 });
54}
55
56#[macro_export]
60macro_rules! info_once {
61 ($($arg:tt)+) => ({
62 $crate::once!($crate::info!($($arg)+))
63 });
64}
65
66#[macro_export]
70macro_rules! warn_once {
71 ($($arg:tt)+) => ({
72 $crate::once!($crate::warn!($($arg)+))
73 });
74}
75
76#[macro_export]
80macro_rules! error_once {
81 ($($arg:tt)+) => ({
82 $crate::once!($crate::error!($($arg)+))
83 });
84}