switchboard_common/
macros.rs

1/// Macro used to wrap client-only modules
2#[macro_export]
3macro_rules! cfg_client {
4    ($($item:item)*) => {
5        $(
6            #[cfg(feature = "client")]
7            #[cfg_attr(doc_cfg, doc(cfg(feature = "client")))]
8            $item
9        )*
10    }
11}
12
13/// Macro used to wrap exclusively non-client modules
14#[macro_export]
15macro_rules! cfg_not_client {
16    ($($item:item)*) => {
17        $(
18            #[cfg(not(feature = "client"))]
19            #[cfg_attr(doc_cfg, doc(cfg(not(feature = "client"))))]
20            $item
21        )*
22    }
23}
24
25/// Macro used to wrap client-only modules
26#[macro_export]
27macro_rules! cfg_ipfs{
28    ($($item:item)*) => {
29        $(
30            #[cfg(feature = "ipfs")]
31            #[cfg_attr(doc_cfg, doc(cfg(feature = "ipfs")))]
32            $item
33        )*
34    }
35}
36
37// /// Macro used to wrap solana exclusive modules
38// #[macro_export]
39// macro_rules! cfg_solana {
40//     ($($item:item)*) => {
41//         $(
42//             #[cfg(feature = "solana")]
43//             #[cfg_attr(doc_cfg, doc(cfg(feature = "solana")))]
44//             $item
45//         )*
46//     }
47// }
48
49/// Retry a given expression a specified number of times with a delay between each attempt.
50///
51/// # Arguments
52///
53/// * `attempts` - The number of attempts to make.
54/// * `delay_ms` - The delay in milliseconds between each attempt.
55/// * `expr` - The expression to be retried.
56///
57/// # Returns
58///
59/// Returns a `Result` containing the value of the expression if it succeeds within the specified number of attempts,
60/// or an error if it fails on all attempts.
61///
62/// # Examples
63/// ```
64/// use switchboard_common::retry;
65///
66/// // Retry a blockhash fetch 3 times with a delay of 500ms in between each failure
67/// let blockhash = retry!(3, 500, rpc.get_latest_blockhash().await)
68///     .await
69///     .map_err(|_| SbError::SolanaBlockhashError)?;
70/// ```
71#[cfg(not(target_os = "solana"))]
72#[cfg_attr(doc_cfg, doc(cfg(not(target_os = "solana"))))]
73#[macro_export]
74macro_rules! retry {
75    ($attempts:expr, $delay_ms:expr, $expr:expr) => {{
76        async {
77            let mut attempts = $attempts;
78            loop {
79                match $expr {
80                    Ok(val) => break Ok(val),
81                    Err(_) if attempts > 1 => {
82                        attempts -= 1;
83                        tokio::time::sleep(tokio::time::Duration::from_millis($delay_ms)).await;
84                    }
85                    Err(e) => break Err(e),
86                }
87            }
88        }
89    }};
90}
91
92/// Retry a given expression a specified number of times with a delay between each attempt.
93/// This will block the current thread until a value is resolved or the maximum number of attempts is reached.
94///
95/// # Arguments
96///
97/// * `attempts` - The number of attempts to make.
98/// * `delay_ms` - The delay in milliseconds between each attempt.
99/// * `expr` - The expression to be retried.
100///
101/// # Returns
102///
103/// Returns a `Result` containing the value of the expression if it succeeds within the specified number of attempts,
104/// or an error if it fails on all attempts.
105///
106/// # Examples
107/// ```
108/// use switchboard_common::blocking_retry;
109///
110/// // Retry a blockhash fetch 3 times with a delay of 500ms in between each failure
111/// let blockhash = blocking_retry!(3, 500, rpc.get_latest_blockhash())
112///     .map_err(|_| SbError::SolanaBlockhashError)?;
113/// ```
114#[cfg(not(target_os = "solana"))]
115#[cfg_attr(doc_cfg, doc(cfg(not(target_os = "solana"))))]
116#[macro_export]
117macro_rules! blocking_retry {
118    ($attempts:expr, $delay_ms:expr, $expr:expr) => {{
119        let mut attempts = $attempts;
120        loop {
121            match $expr {
122                Ok(val) => break Ok(val),
123                Err(_) if attempts > 1 => {
124                    attempts -= 1;
125                    std::thread::sleep(tokio::time::Duration::from_millis($delay_ms));
126                }
127                Err(e) => break Err(e),
128            }
129        }
130    }};
131}