dialog_expect/
lib.rs

1//! This crate provides a trait [`DialogExpect`], with a function that unwraps [`Option<T>`] and [`Result<T, E>`] or shows a dialog box and panics. There is also an alternative to the `panic!()` macro that is the same thing, but it shows a dialog box first.
2
3use native_dialog::{MessageDialog, MessageType};
4
5/// A trait with 1 function, `dialog_expect`, which is implemented for [`std::option::Option<T>`] and [`std::result::Result<T, E>`].
6pub trait DialogExpect<T> {
7    /// Takes `self` and returns the contained value, or shows an error message in a dialog box.
8    /// ### Failures
9    /// This function can fail (nothing will happen, but the program will still panic with the message to stdout) if there is no way to show a dialog box (most likely unsupported platform).
10    fn dialog_expect(self, title: &str, msg: &str) -> T;
11}
12
13impl<T> DialogExpect<T> for std::option::Option<T> {
14    fn dialog_expect(self, title: &str, msg: &str) -> T {
15        match self {
16            Some(v) => v,
17            None => {
18                dialog_panic_internal(title, msg);
19            }
20        }
21    }
22}
23
24impl<T, E> DialogExpect<T> for std::result::Result<T, E> {
25    fn dialog_expect(self, title: &str, msg: &str) -> T {
26        match self {
27            Ok(v) => v,
28            Err(_) => {
29                dialog_panic_internal(title, msg);
30            }
31        }
32    }
33}
34
35#[allow(unused_must_use)]
36#[allow(dead_code)]
37pub(crate) fn dialog_panic_internal(title: &str, msg: &str) -> ! {
38    MessageDialog::new()
39        .set_title(title)
40        .set_text(msg)
41        .set_type(MessageType::Error)
42        .show_alert();
43
44    panic!("{msg}");
45}
46
47/// An alternative to `panic!()` showing a dialog box. This is a function because I honestly couldn't figure out how to have a macro taking multiple args.
48pub fn dialog_panic(title: &str, msg: &str) -> ! {
49    dialog_panic_internal(title, msg);
50}