2024-03-14 22:35:33 +00:00
|
|
|
/// Provides implementations of methods required by the `Module` trait
|
|
|
|
/// which cannot be included as part of the trait.
|
|
|
|
///
|
|
|
|
/// This removes the need to add the same boilerplate method definitions
|
|
|
|
/// to every module implementation.
|
|
|
|
///
|
|
|
|
/// # Usage:
|
|
|
|
///
|
|
|
|
/// ```rs
|
|
|
|
/// impl Module for ClockModule {
|
|
|
|
/// type SendMessage = DateTime<Local>;
|
|
|
|
/// type ReceiveMessage = ();
|
|
|
|
///
|
|
|
|
/// module_impl!("clock");
|
|
|
|
/// }
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! module_impl {
|
|
|
|
($name:literal) => {
|
|
|
|
fn name() -> &'static str {
|
|
|
|
$name
|
|
|
|
}
|
|
|
|
|
|
|
|
fn take_common(&mut self) -> $crate::config::CommonConfig {
|
|
|
|
self.common.take().expect("common config to exist")
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-12-11 22:45:52 +00:00
|
|
|
/// Sends a message on an asynchronous `Sender` using `send()`
|
|
|
|
/// Panics if the message cannot be sent.
|
|
|
|
///
|
2023-06-22 23:07:40 +01:00
|
|
|
/// # Usage:
|
2022-12-11 22:45:52 +00:00
|
|
|
///
|
|
|
|
/// ```rs
|
|
|
|
/// send_async!(tx, "my message");
|
|
|
|
/// ```
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! send_async {
|
|
|
|
($tx:expr, $msg:expr) => {
|
|
|
|
$tx.send($msg).await.expect($crate::error::ERR_CHANNEL_SEND)
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Sends a message on an synchronous `Sender` using `send()`
|
|
|
|
/// Panics if the message cannot be sent.
|
|
|
|
///
|
2023-06-22 23:07:40 +01:00
|
|
|
/// # Usage:
|
2022-12-11 22:45:52 +00:00
|
|
|
///
|
|
|
|
/// ```rs
|
|
|
|
/// send!(tx, "my message");
|
|
|
|
/// ```
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! send {
|
|
|
|
($tx:expr, $msg:expr) => {
|
|
|
|
$tx.send($msg).expect($crate::error::ERR_CHANNEL_SEND)
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Sends a message on an synchronous `Sender` using `try_send()`
|
|
|
|
/// Panics if the message cannot be sent.
|
|
|
|
///
|
2023-06-22 23:07:40 +01:00
|
|
|
/// # Usage:
|
2022-12-11 22:45:52 +00:00
|
|
|
///
|
|
|
|
/// ```rs
|
|
|
|
/// try_send!(tx, "my message");
|
|
|
|
/// ```
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! try_send {
|
|
|
|
($tx:expr, $msg:expr) => {
|
|
|
|
$tx.try_send($msg).expect($crate::error::ERR_CHANNEL_SEND)
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2023-12-17 23:51:43 +00:00
|
|
|
/// Spawns a `GLib` future on the local thread, and calls `rx.recv()`
|
|
|
|
/// in a loop.
|
|
|
|
///
|
|
|
|
/// This allows use of `GObjects` and futures in the same context.
|
|
|
|
///
|
|
|
|
/// For use with receivers which return a `Result`.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rs
|
|
|
|
/// let (tx, mut rx) = broadcast::channel(32);
|
|
|
|
/// glib_recv(rx, msg => println!("{msg}"));
|
|
|
|
/// ```
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! glib_recv {
|
2023-12-31 00:50:03 +00:00
|
|
|
($rx:expr, $val:ident => $expr:expr) => {{
|
2023-12-17 23:51:43 +00:00
|
|
|
glib::spawn_future_local(async move {
|
2023-12-31 00:50:03 +00:00
|
|
|
// re-delcare in case ie `context.subscribe()` is passed directly
|
|
|
|
let mut rx = $rx;
|
2024-01-29 23:30:25 +00:00
|
|
|
loop {
|
|
|
|
match rx.recv().await {
|
|
|
|
Ok($val) => $expr,
|
|
|
|
Err(tokio::sync::broadcast::error::RecvError::Lagged(count)) => {
|
|
|
|
tracing::warn!("Channel lagged behind by {count}, this may result in unexpected or broken behaviour");
|
|
|
|
}
|
|
|
|
Err(err) => {
|
|
|
|
tracing::error!("{err:?}");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2023-12-17 23:51:43 +00:00
|
|
|
}
|
|
|
|
});
|
2023-12-31 00:50:03 +00:00
|
|
|
}};
|
2023-12-17 23:51:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Spawns a `GLib` future on the local thread, and calls `rx.recv()`
|
|
|
|
/// in a loop.
|
|
|
|
///
|
|
|
|
/// This allows use of `GObjects` and futures in the same context.
|
|
|
|
///
|
|
|
|
/// For use with receivers which return an `Option`,
|
|
|
|
/// such as Tokio's `mpsc` channel.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rs
|
|
|
|
/// let (tx, mut rx) = broadcast::channel(32);
|
|
|
|
/// glib_recv_mpsc(rx, msg => println!("{msg}"));
|
|
|
|
/// ```
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! glib_recv_mpsc {
|
2023-12-31 00:50:03 +00:00
|
|
|
($rx:expr, $val:ident => $expr:expr) => {{
|
2023-12-17 23:51:43 +00:00
|
|
|
glib::spawn_future_local(async move {
|
2023-12-31 00:50:03 +00:00
|
|
|
// re-delcare in case ie `context.subscribe()` is passed directly
|
|
|
|
let mut rx = $rx;
|
|
|
|
while let Some($val) = rx.recv().await {
|
2023-12-17 23:51:43 +00:00
|
|
|
$expr
|
|
|
|
}
|
|
|
|
});
|
2023-12-31 00:50:03 +00:00
|
|
|
}};
|
2023-12-17 23:51:43 +00:00
|
|
|
}
|
|
|
|
|
2022-12-11 22:45:52 +00:00
|
|
|
/// Locks a `Mutex`.
|
|
|
|
/// Panics if the `Mutex` cannot be locked.
|
|
|
|
///
|
2023-06-22 23:07:40 +01:00
|
|
|
/// # Usage:
|
2022-12-11 22:45:52 +00:00
|
|
|
///
|
|
|
|
/// ```rs
|
|
|
|
/// let mut val = lock!(my_mutex);
|
|
|
|
/// ```
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! lock {
|
2023-04-29 22:09:14 +01:00
|
|
|
($mutex:expr) => {{
|
|
|
|
tracing::trace!("Locking {}", std::stringify!($mutex));
|
2022-12-11 22:45:52 +00:00
|
|
|
$mutex.lock().expect($crate::error::ERR_MUTEX_LOCK)
|
2023-04-29 22:09:14 +01:00
|
|
|
}};
|
2022-12-11 22:45:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Gets a read lock on a `RwLock`.
|
|
|
|
/// Panics if the `RwLock` cannot be locked.
|
|
|
|
///
|
2023-06-22 23:07:40 +01:00
|
|
|
/// # Usage:
|
2022-12-11 22:45:52 +00:00
|
|
|
///
|
|
|
|
/// ```rs
|
|
|
|
/// let val = read_lock!(my_rwlock);
|
|
|
|
/// ```
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! read_lock {
|
|
|
|
($rwlock:expr) => {
|
|
|
|
$rwlock.read().expect($crate::error::ERR_READ_LOCK)
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Gets a write lock on a `RwLock`.
|
|
|
|
/// Panics if the `RwLock` cannot be locked.
|
|
|
|
///
|
2023-06-22 23:07:40 +01:00
|
|
|
/// # Usage:
|
2022-12-11 22:45:52 +00:00
|
|
|
///
|
|
|
|
/// ```rs
|
|
|
|
/// let mut val = write_lock!(my_rwlock);
|
|
|
|
/// ```
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! write_lock {
|
|
|
|
($rwlock:expr) => {
|
|
|
|
$rwlock.write().expect($crate::error::ERR_WRITE_LOCK)
|
|
|
|
};
|
|
|
|
}
|
2023-06-22 23:07:40 +01:00
|
|
|
|
|
|
|
/// Wraps `val` in a new `Arc<Mutex<T>>`.
|
|
|
|
///
|
|
|
|
/// # Usage:
|
|
|
|
///
|
|
|
|
/// ```rs
|
|
|
|
/// let val = arc_mut!(MyService::new());
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! arc_mut {
|
|
|
|
($val:expr) => {
|
2023-06-29 23:16:31 +01:00
|
|
|
std::sync::Arc::new(std::sync::Mutex::new($val))
|
2023-06-22 23:07:40 +01:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Wraps `val` in a new `Arc<RwLock<T>>`.
|
|
|
|
///
|
|
|
|
/// # Usage:
|
|
|
|
///
|
|
|
|
/// ```rs
|
|
|
|
/// let val = arc_rw!(MyService::new());
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! arc_rw {
|
|
|
|
($val:expr) => {
|
|
|
|
std::sync::Arc::new(std::sync::RwLock::new($val))
|
|
|
|
};
|
|
|
|
}
|
2023-04-01 13:07:47 +01:00
|
|
|
|
2024-03-29 00:29:13 +00:00
|
|
|
/// Wraps `val` in a new `Rc<RefCell<T>>`.
|
|
|
|
///
|
|
|
|
/// # Usage
|
|
|
|
///
|
|
|
|
/// ```rs
|
|
|
|
/// let val = rc_mut!(MyService::new())
|
|
|
|
/// ```
|
2023-04-01 13:07:47 +01:00
|
|
|
#[macro_export]
|
|
|
|
macro_rules! rc_mut {
|
|
|
|
($val:expr) => {
|
|
|
|
std::rc::Rc::new(std::cell::RefCell::new($val))
|
|
|
|
};
|
|
|
|
}
|