From ffad9696bf06da5c495bb78c9ec859597931a069 Mon Sep 17 00:00:00 2001 From: Julian Sparber Date: Thu, 27 May 2021 12:38:19 +0200 Subject: [PATCH] error: Add 'Error' object for handling error --- po/POTFILES.in | 1 + src/error.rs | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 2 ++ src/meson.build | 1 + 4 files changed, 67 insertions(+) create mode 100644 src/error.rs diff --git a/po/POTFILES.in b/po/POTFILES.in index 89fe36a3..bcbe1a39 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -33,6 +33,7 @@ src/components/label_with_widgets.rs src/components/mod.rs src/components/spinner_button.rs src/components/pill.rs +src/error.rs src/login.rs src/main.rs src/secret.rs diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 00000000..c4d3e192 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,63 @@ +use gtk::{glib, subclass::prelude::*}; + +use matrix_sdk::Error as MatrixError; + +mod imp { + use super::*; + use once_cell::sync::OnceCell; + use std::cell::RefCell; + + #[derive(Default)] + pub struct Error { + pub matrix_error: OnceCell, + pub widget_builder: + RefCell Option + 'static>>>, + } + + #[glib::object_subclass] + impl ObjectSubclass for Error { + const NAME: &'static str = "Error"; + type Type = super::Error; + type ParentType = glib::Object; + } + + impl ObjectImpl for Error {} +} + +glib::wrapper! { + pub struct Error(ObjectSubclass); +} + +/// An `Error` that can be shown in the UI +impl Error { + pub fn new Option + 'static>(error: MatrixError, f: F) -> Self { + let obj: Self = glib::Object::new(&[]).expect("Failed to create Error"); + obj.set_matrix_error(error); + obj.set_widget_builder(f); + obj + } + + fn set_matrix_error(&self, error: MatrixError) { + let priv_ = imp::Error::from_instance(&self); + priv_.matrix_error.set(error).unwrap() + } + + pub fn matrix_error(&self) -> &MatrixError { + let priv_ = imp::Error::from_instance(&self); + priv_.matrix_error.get().unwrap() + } + + /// Set a function that builds the widget used to display this error in the UI + pub fn set_widget_builder Option + 'static>(&self, f: F) { + let priv_ = imp::Error::from_instance(&self); + priv_.widget_builder.replace(Some(Box::new(f))); + } + + /// Produces a widget via the function set in `Self::set_widget_builder()` + pub fn widget(&self) -> Option { + let priv_ = imp::Error::from_instance(&self); + let widget_builder = priv_.widget_builder.borrow(); + let widget_builder = widget_builder.as_ref()?; + widget_builder(self) + } +} diff --git a/src/main.rs b/src/main.rs index ea741574..d837c266 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,7 @@ mod application; mod config; mod components; +mod error; mod login; mod secret; mod session; @@ -14,6 +15,7 @@ mod utils; mod window; use self::application::Application; +use self::error::Error; use self::login::Login; use self::session::Session; use self::window::Window; diff --git a/src/meson.build b/src/meson.build index 2fd00aca..b2c8fd8c 100644 --- a/src/meson.build +++ b/src/meson.build @@ -26,6 +26,7 @@ sources = files( 'components/pill.rs', 'components/spinner_button.rs', 'config.rs', + 'error.rs', 'main.rs', 'window.rs', 'login.rs',