mirror of
https://github.com/Zedfrigg/ironbar.git
synced 2025-07-03 03:31:03 +02:00
refactor: better error handling for client initialization
This commit is contained in:
parent
1b35354272
commit
9245188af7
10 changed files with 97 additions and 49 deletions
|
@ -1,4 +1,4 @@
|
|||
use crate::{await_sync, register_client};
|
||||
use crate::{await_sync, register_fallible_client};
|
||||
use cfg_if::cfg_if;
|
||||
use color_eyre::{Help, Report, Result};
|
||||
use std::fmt::{Debug, Display, Formatter};
|
||||
|
@ -141,4 +141,4 @@ pub trait WorkspaceClient: Debug + Send + Sync {
|
|||
fn subscribe_workspace_change(&self) -> broadcast::Receiver<WorkspaceUpdate>;
|
||||
}
|
||||
|
||||
register_client!(dyn WorkspaceClient, workspaces);
|
||||
register_fallible_client!(dyn WorkspaceClient, workspaces);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::Ironbar;
|
||||
use crate::{await_sync, Ironbar};
|
||||
use color_eyre::Result;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[cfg(feature = "clipboard")]
|
||||
|
@ -38,6 +39,8 @@ pub struct Clients {
|
|||
volume: Option<Arc<volume::Client>>,
|
||||
}
|
||||
|
||||
pub type ClientResult<T> = Result<Arc<T>>;
|
||||
|
||||
impl Clients {
|
||||
pub(crate) fn new() -> Self {
|
||||
Self::default()
|
||||
|
@ -59,13 +62,17 @@ impl Clients {
|
|||
}
|
||||
|
||||
#[cfg(feature = "workspaces")]
|
||||
pub fn workspaces(&mut self) -> Arc<dyn compositor::WorkspaceClient> {
|
||||
// TODO: Error handling here isn't great - should throw a user-friendly error & exit
|
||||
self.workspaces
|
||||
.get_or_insert_with(|| {
|
||||
compositor::Compositor::create_workspace_client().expect("to be valid compositor")
|
||||
})
|
||||
.clone()
|
||||
pub fn workspaces(&mut self) -> ClientResult<dyn compositor::WorkspaceClient> {
|
||||
let client = match &self.workspaces {
|
||||
Some(workspaces) => workspaces.clone(),
|
||||
None => {
|
||||
let client = compositor::Compositor::create_workspace_client()?;
|
||||
self.workspaces.replace(client.clone());
|
||||
client
|
||||
}
|
||||
};
|
||||
|
||||
Ok(client)
|
||||
}
|
||||
|
||||
#[cfg(feature = "music")]
|
||||
|
@ -77,29 +84,35 @@ impl Clients {
|
|||
}
|
||||
|
||||
#[cfg(feature = "notifications")]
|
||||
pub fn notifications(&mut self) -> Arc<swaync::Client> {
|
||||
self.notifications
|
||||
.get_or_insert_with(|| {
|
||||
Arc::new(crate::await_sync(async { swaync::Client::new().await }))
|
||||
})
|
||||
.clone()
|
||||
pub fn notifications(&mut self) -> ClientResult<swaync::Client> {
|
||||
let client = match &self.notifications {
|
||||
Some(client) => client.clone(),
|
||||
None => {
|
||||
let client = await_sync(async { swaync::Client::new().await })?;
|
||||
let client = Arc::new(client);
|
||||
self.notifications.replace(client.clone());
|
||||
client
|
||||
}
|
||||
};
|
||||
|
||||
Ok(client)
|
||||
}
|
||||
|
||||
#[cfg(feature = "tray")]
|
||||
pub fn tray(&mut self) -> Arc<tray::Client> {
|
||||
// TODO: Error handling here isn't great - should throw a user-friendly error
|
||||
self.tray
|
||||
.get_or_insert_with(|| {
|
||||
Arc::new(crate::await_sync(async {
|
||||
let service_name =
|
||||
format!("{}-{}", env!("CARGO_CRATE_NAME"), Ironbar::unique_id());
|
||||
pub fn tray(&mut self) -> ClientResult<tray::Client> {
|
||||
let client = match &self.tray {
|
||||
Some(client) => client.clone(),
|
||||
None => {
|
||||
let service_name = format!("{}-{}", env!("CARGO_CRATE_NAME"), Ironbar::unique_id());
|
||||
|
||||
tray::Client::new(&service_name)
|
||||
.await
|
||||
.expect("to be able to start client")
|
||||
}))
|
||||
})
|
||||
.clone()
|
||||
let client = await_sync(async { tray::Client::new(&service_name).await })?;
|
||||
let client = Arc::new(client);
|
||||
self.tray.replace(client.clone());
|
||||
client
|
||||
}
|
||||
};
|
||||
|
||||
Ok(client)
|
||||
}
|
||||
|
||||
#[cfg(feature = "upower")]
|
||||
|
@ -126,6 +139,14 @@ pub trait ProvidesClient<T: ?Sized> {
|
|||
fn provide(&self) -> Arc<T>;
|
||||
}
|
||||
|
||||
/// Types implementing this trait
|
||||
/// indicate that they provide a singleton client instance of type `T`,
|
||||
/// which may fail to be created.
|
||||
pub trait ProvidesFallibleClient<T: ?Sized> {
|
||||
/// Returns a singleton client instance of type `T`.
|
||||
fn try_provide(&self) -> ClientResult<T>;
|
||||
}
|
||||
|
||||
/// Generates a `ProvidesClient` impl block on `WidgetContext`
|
||||
/// for the provided `$ty` (first argument) client type.
|
||||
///
|
||||
|
@ -148,3 +169,26 @@ macro_rules! register_client {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Generates a `ProvidesClient` impl block on `WidgetContext`
|
||||
/// for the provided `$ty` (first argument) client type.
|
||||
///
|
||||
/// The implementation calls `$method` (second argument)
|
||||
/// on the `Clients` struct to obtain the client instance.
|
||||
///
|
||||
/// # Example
|
||||
/// `register_client!(Client, clipboard);`
|
||||
#[macro_export]
|
||||
macro_rules! register_fallible_client {
|
||||
($ty:ty, $method:ident) => {
|
||||
impl<TSend, TReceive> $crate::clients::ProvidesFallibleClient<$ty>
|
||||
for $crate::modules::WidgetContext<TSend, TReceive>
|
||||
where
|
||||
TSend: Clone,
|
||||
{
|
||||
fn try_provide(&self) -> color_eyre::Result<std::sync::Arc<$ty>> {
|
||||
self.ironbar.clients.borrow_mut().$method()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
mod dbus;
|
||||
|
||||
use crate::{register_client, send, spawn};
|
||||
use crate::{register_fallible_client, send, spawn};
|
||||
use color_eyre::{Report, Result};
|
||||
use dbus::SwayNcProxy;
|
||||
use serde::Deserialize;
|
||||
|
@ -24,9 +24,9 @@ type GetSubscribeData = (bool, bool, u32, bool);
|
|||
impl From<GetSubscribeData> for Event {
|
||||
fn from((dnd, cc_open, count, inhibited): (bool, bool, u32, bool)) -> Self {
|
||||
Self {
|
||||
count,
|
||||
dnd,
|
||||
cc_open,
|
||||
count,
|
||||
inhibited,
|
||||
}
|
||||
}
|
||||
|
@ -40,15 +40,13 @@ pub struct Client {
|
|||
}
|
||||
|
||||
impl Client {
|
||||
pub async fn new() -> Self {
|
||||
let dbus = Box::pin(zbus::Connection::session())
|
||||
.await
|
||||
.expect("failed to create connection to system bus");
|
||||
pub async fn new() -> Result<Self> {
|
||||
let dbus = Box::pin(zbus::Connection::session()).await?;
|
||||
|
||||
let proxy = SwayNcProxy::new(&dbus).await.unwrap();
|
||||
let proxy = SwayNcProxy::new(&dbus).await?;
|
||||
let (tx, rx) = broadcast::channel(8);
|
||||
|
||||
let mut stream = proxy.receive_subscribe_v2().await.unwrap();
|
||||
let mut stream = proxy.receive_subscribe_v2().await?;
|
||||
|
||||
{
|
||||
let tx = tx.clone();
|
||||
|
@ -62,7 +60,7 @@ impl Client {
|
|||
});
|
||||
}
|
||||
|
||||
Self { proxy, tx, _rx: rx }
|
||||
Ok(Self { proxy, tx, _rx: rx })
|
||||
}
|
||||
|
||||
pub fn subscribe(&self) -> broadcast::Receiver<Event> {
|
||||
|
@ -85,4 +83,4 @@ impl Client {
|
|||
}
|
||||
}
|
||||
|
||||
register_client!(Client, notifications);
|
||||
register_fallible_client!(Client, notifications);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::register_client;
|
||||
use crate::register_fallible_client;
|
||||
pub use system_tray::client::Client;
|
||||
|
||||
register_client!(Client, tray);
|
||||
register_fallible_client!(Client, tray);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue