macro_toolset/
lib.rs

1//! Dev deps: some useful macros.
2
3#[cfg(feature = "feat-base64")]
4pub mod base64;
5#[cfg(feature = "feat-hash")]
6pub mod hash;
7pub mod misc;
8#[cfg(feature = "feat-random")]
9pub mod random;
10#[cfg(feature = "feat-string")]
11pub mod string;
12
13#[cfg(feature = "feat-string")]
14#[deprecated(since = "0.8.0", note = "Use `string` in release version instead")]
15pub use string as string_v2;
16
17#[macro_export]
18/// Faster way to get current timestamp other than
19/// `chrono::Local::now().timestamp()`, 12x faster on my machine.
20///
21/// # Example
22///
23/// ```rust
24/// # use macro_toolset::now;
25/// let now_ts_sec = now!().as_secs(); // Seconds since UNIX_EPOCH
26/// let now_ts_millis = now!().as_millis(); // Milliseconds since UNIX_EPOCH
27/// ```
28///
29/// See [`Duration`](https://doc.rust-lang.org/std/time/struct.Duration.html) for more details.
30macro_rules! now {
31    () => {{
32        match std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH) {
33            Ok(t) => t,
34            Err(_) => panic!("SystemTime before UNIX EPOCH!"),
35        }
36    }};
37}
38
39#[macro_export]
40/// Init `tracing_subscriber` with default settings.
41///
42/// This is useful when running tests.
43macro_rules! init_tracing_simple {
44    () => {{
45        use tracing::level_filters::LevelFilter;
46        use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter, Layer};
47
48        let fmt_layer = tracing_subscriber::fmt::layer().with_filter(
49            EnvFilter::builder()
50                .with_default_directive(LevelFilter::DEBUG.into())
51                .from_env_lossy()
52                .add_directive("otel::tracing=trace".parse().unwrap())
53                .add_directive("h2=error".parse().unwrap())
54                .add_directive("tower=error".parse().unwrap())
55                .add_directive("hyper=error".parse().unwrap()),
56        );
57
58        tracing_subscriber::registry().with(fmt_layer).init();
59    }};
60}
61
62#[macro_export]
63/// Helper macro for creating a wrapper type.
64///
65/// The wrapper type will implement [`Deref`](std::ops::Deref),
66/// [`DerefMut`](std::ops::DerefMut), [`From`] and [`AsRef`].
67///
68/// # Example
69///
70/// ```rust
71/// # use macro_toolset::wrapper;
72/// wrapper!(pub MyString(String));
73/// // Derive is OK!
74/// wrapper!(pub MyStringDerived(String), derive(Debug, Clone, PartialEq, Eq, Hash));
75/// // Lifetime is supported too!
76/// wrapper!(pub MyStringLifetime<'a>(&'a str));
77/// wrapper!(pub MyStringLifetimePubDerived<'a>(pub &'a str), derive(Debug, Clone, PartialEq, Eq, Hash));
78/// ```
79///
80/// Reference: <https://stackoverflow.com/a/61189128>
81macro_rules! wrapper {
82    ($(#[$outer:meta])* $vis:vis $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner:ty) $(, <$($plt_name:ident: $plt:lifetime),+>)? $(, derive($($derive:path),+))?) => {
83        $(#[$outer])*
84        $(#[derive($($derive),+)])?
85        #[repr(transparent)]
86        #[doc = concat!("\n\nThis is an auto-generated wrapper over `", stringify!($inner), "`")]
87        $vis struct $name$(<$($lt),+>)? {
88            /// Inner value
89            $inner_vis inner: $inner,
90            $($(
91                $plt_name: std::marker::PhantomData<&$plt ()>,
92            ),+)?
93        }
94
95        impl$(<$($lt),+>)? From<$inner> for $name$(<$($lt),+>)? {
96            #[inline]
97            fn from(inner: $inner) -> Self {
98                Self {
99                    inner,
100                    $($($plt_name: std::marker::PhantomData),+)?
101                }
102            }
103        }
104
105        impl$(<$($lt),+>)? std::borrow::Borrow<$inner> for $name$(<$($lt),+>)? {
106            fn borrow(&self) -> &$inner {
107                &self.inner
108            }
109        }
110
111        impl$(<$($lt),+>)? std::ops::Deref for $name$(<$($lt),+>)? {
112            type Target = $inner;
113
114            fn deref(&self) -> &Self::Target {
115                &self.inner
116            }
117        }
118
119        impl$(<$($lt),+>)? std::ops::DerefMut for $name$(<$($lt),+>)? {
120            fn deref_mut(&mut self) -> &mut Self::Target {
121                &mut self.inner
122            }
123        }
124
125        impl$(<$($lt),+>)? AsRef<$inner> for $name$(<$($lt),+>)? {
126            fn as_ref(&self) -> &$inner {
127                &self.inner
128            }
129        }
130
131        impl$(<$($lt),+>)? $name$(<$($lt),+>)? {
132            #[inline]
133            #[doc = concat!("Creates a new instance of [`", stringify!($name), "`]")]
134            $vis const fn new(inner: $inner) -> Self {
135                Self {
136                    inner,
137                    $($($plt_name: std::marker::PhantomData),+)?
138                }
139            }
140        }
141    };
142}
143
144#[cfg(test)]
145mod tests {
146    #![allow(unused)]
147    #![allow(unreachable_pub)]
148
149    // Simple wrapper!
150    wrapper!(pub MyString(String));
151
152    wrapper!(#[derive(Debug)] pub MyStringPub(pub String));
153    wrapper!(pub MyStringPubCrate(pub(crate) String));
154    // Derive is OK!
155    wrapper!(pub MyStringDerived(String), derive(Debug, Clone, PartialEq, Eq, Hash));
156    wrapper! {
157        #[derive(Debug, Clone, PartialEq, Eq, Hash)]
158        /// MyStringDerived
159        pub MyStringDerived2(String)
160    }
161    wrapper!(pub MyStringPubInnerDerived(pub String), derive(Debug, Clone, PartialEq, Eq, Hash));
162    wrapper!(pub MyStringPubCrateInnerDerived(pub(crate) String), derive(Debug, Clone, PartialEq, Eq, Hash));
163    // Lifetime is supported too!
164    wrapper!(pub MyStringLifetime<'a>(&'a str));
165    wrapper!(pub MyStringLifetimePubInner<'a>(pub &'a str));
166    wrapper!(pub MyStringLifetimePubCrateInner<'a>(pub(crate) &'a str));
167    wrapper!(pub MyStringLifetimePubDerived<'a>(pub &'a str), derive(Debug, Clone, PartialEq, Eq, Hash));
168    wrapper!(pub MyStringLifetimePubMutDerived<'a>(pub &'a mut str), derive(Debug, PartialEq, Eq, Hash));
169    // Generic is supported too!
170    wrapper!(pub MyStringLifetimePubT<T>(pub T), derive(Debug, Clone));
171    // Complicated!
172    wrapper!(pub MyStringLifetimePubRefT<'a, T>(pub &'a T), derive(Debug, Clone));
173}