From 5e21cbcca6cc30d725acdea0f6561cfd6acdcc3c Mon Sep 17 00:00:00 2001 From: Jake Stanger Date: Sun, 11 Dec 2022 22:45:52 +0000 Subject: [PATCH] refactor: macros to reduce repeated code --- src/bar.rs | 19 +++---- src/bridge_channel.rs | 4 +- src/clients/wayland/client.rs | 38 +++++-------- src/clients/wayland/toplevel.rs | 6 +- src/dynamic_string.rs | 23 +++----- src/macros.rs | 89 ++++++++++++++++++++++++++++++ src/main.rs | 1 + src/modules/clock.rs | 17 ++---- src/modules/custom.rs | 26 ++++----- src/modules/focused.rs | 15 +++-- src/modules/launcher/item.rs | 32 +++++------ src/modules/launcher/mod.rs | 32 +++++------ src/modules/mpd.rs | 31 ++++------- src/modules/sysinfo.rs | 97 ++++++--------------------------- src/modules/tray.rs | 16 +++--- src/modules/workspaces.rs | 17 +++--- src/script.rs | 6 +- src/style.rs | 4 +- 18 files changed, 225 insertions(+), 248 deletions(-) create mode 100644 src/macros.rs diff --git a/src/bar.rs b/src/bar.rs index a114663..aa4e867 100644 --- a/src/bar.rs +++ b/src/bar.rs @@ -4,7 +4,7 @@ use crate::dynamic_string::DynamicString; use crate::modules::{Module, ModuleInfo, ModuleLocation, ModuleUpdateEvent, WidgetContext}; use crate::popup::Popup; use crate::script::{OutputStream, Script}; -use crate::{await_sync, error as err, Config}; +use crate::{await_sync, read_lock, send, write_lock, Config}; use color_eyre::Result; use gtk::gdk::Monitor; use gtk::prelude::*; @@ -251,10 +251,7 @@ where /// Registers the popup content with the popup. fn register_popup_content(popup: &Arc>, id: usize, popup_content: gtk::Box) { - popup - .write() - .expect(err::ERR_WRITE_LOCK) - .register_content(id, popup_content); + write_lock!(popup).register_content(id, popup_content); } /// Sets up the bridge channel receiver @@ -277,14 +274,14 @@ fn setup_receiver( match ev { ModuleUpdateEvent::Update(update) => { if has_popup { - p_tx.send(update.clone()).expect(err::ERR_CHANNEL_SEND); + send!(p_tx, update.clone()); } - w_tx.send(update).expect(err::ERR_CHANNEL_SEND); + send!(w_tx, update); } ModuleUpdateEvent::TogglePopup(geometry) => { debug!("Toggling popup for {} [#{}]", name, id); - let popup = popup.read().expect(err::ERR_READ_LOCK); + let popup = read_lock!(popup); if popup.is_visible() { popup.hide(); } else { @@ -295,7 +292,7 @@ fn setup_receiver( ModuleUpdateEvent::OpenPopup(geometry) => { debug!("Opening popup for {} [#{}]", name, id); - let popup = popup.read().expect(err::ERR_READ_LOCK); + let popup = read_lock!(popup); popup.hide(); popup.show_content(id); popup.show(geometry); @@ -303,7 +300,7 @@ fn setup_receiver( ModuleUpdateEvent::ClosePopup => { debug!("Closing popup for {} [#{}]", name, id); - let popup = popup.read().expect(err::ERR_READ_LOCK); + let popup = read_lock!(popup); popup.hide(); } } @@ -333,7 +330,7 @@ fn setup_module_common_options(container: EventBox, common: CommonConfig) { spawn(async move { script .run(|(_, success)| { - tx.send(success).expect(err::ERR_CHANNEL_SEND); + send!(tx, success); }) .await; }); diff --git a/src/bridge_channel.rs b/src/bridge_channel.rs index 3283de6..2208e0c 100644 --- a/src/bridge_channel.rs +++ b/src/bridge_channel.rs @@ -1,4 +1,4 @@ -use crate::error; +use crate::send; use tokio::spawn; use tokio::sync::mpsc; @@ -22,7 +22,7 @@ impl BridgeChannel { spawn(async move { while let Some(val) = async_rx.recv().await { - sync_tx.send(val).expect(error::ERR_CHANNEL_SEND); + send!(sync_tx, val); } }); diff --git a/src/clients/wayland/client.rs b/src/clients/wayland/client.rs index 6dc610e..b0eb716 100644 --- a/src/clients/wayland/client.rs +++ b/src/clients/wayland/client.rs @@ -2,6 +2,7 @@ use super::toplevel::{ToplevelEvent, ToplevelInfo}; use super::toplevel_manager::listen_for_toplevels; use super::ToplevelChange; use super::{Env, ToplevelHandler}; +use crate::{error as err, send, write_lock}; use color_eyre::Report; use indexmap::IndexMap; use smithay_client_toolkit::environment::Environment; @@ -18,7 +19,6 @@ use wayland_protocols::wlr::unstable::foreign_toplevel::v1::client::{ zwlr_foreign_toplevel_handle_v1::ZwlrForeignToplevelHandleV1, zwlr_foreign_toplevel_manager_v1::ZwlrForeignToplevelManagerV1, }; -use crate::error as err; pub struct WaylandClient { pub outputs: Vec, @@ -47,19 +47,16 @@ impl WaylandClient { .expect("Failed to connect to Wayland compositor"); let outputs = Self::get_outputs(&env); - output_tx - .send(outputs) - .expect(err::ERR_CHANNEL_SEND); + send!(output_tx, outputs); let seats = env.get_all_seats(); - seat_tx - .send( - seats - .into_iter() - .map(|seat| seat.detach()) - .collect::>(), - ) - .expect(err::ERR_CHANNEL_SEND); + send!( + seat_tx, + seats + .into_iter() + .map(|seat| seat.detach()) + .collect::>() + ); let _toplevel_manager = env.require_global::(); @@ -67,20 +64,13 @@ impl WaylandClient { trace!("Received toplevel event: {:?}", event); if event.change == ToplevelChange::Close { - toplevels2 - .write() - .expect(err::ERR_WRITE_LOCK) - .remove(&event.toplevel.id); + write_lock!(toplevels2).remove(&event.toplevel.id); } else { - toplevels2 - .write() - .expect(err::ERR_WRITE_LOCK) + write_lock!(toplevels2) .insert(event.toplevel.id, (event.toplevel.clone(), handle)); } - toplevel_tx2 - .send(event) - .expect(err::ERR_CHANNEL_SEND); + send!(toplevel_tx2, event); }); let mut event_loop = @@ -100,9 +90,7 @@ impl WaylandClient { } }); - let outputs = output_rx - .await - .expect(err::ERR_CHANNEL_RECV); + let outputs = output_rx.await.expect(err::ERR_CHANNEL_RECV); let seats = seat_rx.await.expect(err::ERR_CHANNEL_RECV); diff --git a/src/clients/wayland/toplevel.rs b/src/clients/wayland/toplevel.rs index 57325d8..aab2828 100644 --- a/src/clients/wayland/toplevel.rs +++ b/src/clients/wayland/toplevel.rs @@ -4,7 +4,7 @@ use std::sync::atomic::{AtomicUsize, Ordering}; use tracing::trace; use wayland_client::{DispatchData, Main}; use wayland_protocols::wlr::unstable::foreign_toplevel::v1::client::zwlr_foreign_toplevel_handle_v1::{Event, ZwlrForeignToplevelHandleV1}; -use crate::error; +use crate::write_lock; const STATE_ACTIVE: u32 = 2; const STATE_FULLSCREEN: u32 = 3; @@ -143,9 +143,7 @@ impl Toplevel { let inner = Arc::new(RwLock::new(ToplevelInfo::new())); handle.quick_assign(move |_handle, event, ddata| { - let mut inner = inner - .write() - .expect(error::ERR_WRITE_LOCK); + let mut inner = write_lock!(inner); toplevel_implem(event, &mut inner, &mut callback, ddata); }); diff --git a/src/dynamic_string.rs b/src/dynamic_string.rs index ef09c47..e767af4 100644 --- a/src/dynamic_string.rs +++ b/src/dynamic_string.rs @@ -1,5 +1,5 @@ -use crate::error; use crate::script::{OutputStream, Script}; +use crate::{lock, send}; use gtk::prelude::*; use indexmap::IndexMap; use std::sync::{Arc, Mutex}; @@ -66,10 +66,7 @@ impl DynamicString { for (i, segment) in segments.into_iter().enumerate() { match segment { DynamicStringSegment::Static(str) => { - label_parts - .lock() - .expect(error::ERR_MUTEX_LOCK) - .insert(i, str); + lock!(label_parts).insert(i, str); } DynamicStringSegment::Dynamic(script) => { let tx = tx.clone(); @@ -79,20 +76,16 @@ impl DynamicString { script .run(|(out, _)| { if let OutputStream::Stdout(out) = out { - let mut label_parts = - label_parts.lock().expect(error::ERR_MUTEX_LOCK); + let mut label_parts = lock!(label_parts); - label_parts - // .lock() - // .expect("Failed to get lock on label parts") - .insert(i, out); + label_parts.insert(i, out); let string = label_parts .iter() .map(|(_, part)| part.as_str()) .collect::(); - tx.send(string).expect(error::ERR_CHANNEL_SEND); + send!(tx, string); } }) .await; @@ -103,14 +96,12 @@ impl DynamicString { // initialize { - let label_parts = label_parts - .lock() - .expect(error::ERR_MUTEX_LOCK) + let label_parts = lock!(label_parts) .iter() .map(|(_, part)| part.as_str()) .collect::(); - tx.send(label_parts).expect(error::ERR_CHANNEL_SEND); + send!(tx, label_parts); } rx.attach(None, f); diff --git a/src/macros.rs b/src/macros.rs new file mode 100644 index 0000000..2197024 --- /dev/null +++ b/src/macros.rs @@ -0,0 +1,89 @@ +/// Sends a message on an asynchronous `Sender` using `send()` +/// Panics if the message cannot be sent. +/// +/// Usage: +/// +/// ```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. +/// +/// Usage: +/// +/// ```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. +/// +/// Usage: +/// +/// ```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) + }; +} + +/// Locks a `Mutex`. +/// Panics if the `Mutex` cannot be locked. +/// +/// Usage: +/// +/// ```rs +/// let mut val = lock!(my_mutex); +/// ``` +#[macro_export] +macro_rules! lock { + ($mutex:expr) => { + $mutex.lock().expect($crate::error::ERR_MUTEX_LOCK) + }; +} + +/// Gets a read lock on a `RwLock`. +/// Panics if the `RwLock` cannot be locked. +/// +/// Usage: +/// +/// ```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. +/// +/// Usage: +/// +/// ```rs +/// let mut val = write_lock!(my_rwlock); +/// ``` +#[macro_export] +macro_rules! write_lock { + ($rwlock:expr) => { + $rwlock.write().expect($crate::error::ERR_WRITE_LOCK) + }; +} diff --git a/src/main.rs b/src/main.rs index 09ef4a7..d78a010 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,7 @@ mod dynamic_string; mod error; mod icon; mod logging; +mod macros; mod modules; mod popup; mod script; diff --git a/src/modules/clock.rs b/src/modules/clock.rs index daf7c1d..2156ef9 100644 --- a/src/modules/clock.rs +++ b/src/modules/clock.rs @@ -1,7 +1,7 @@ use crate::config::CommonConfig; -use crate::error; use crate::modules::{Module, ModuleInfo, ModuleUpdateEvent, ModuleWidget, WidgetContext}; use crate::popup::Popup; +use crate::{send_async, try_send}; use chrono::{DateTime, Local}; use color_eyre::Result; use glib::Continue; @@ -47,9 +47,7 @@ impl Module