Skip to main content

zero_dialog/
lib.rs

1//! An ultra-lightweight, dependency-free system dialog library.
2//! Adds no GUI dependencies, requires no linking,
3//! and introduces zero extra code complexity.
4//!
5//! Designed to show system-native dialogs as a last-resort
6//! user-facing error/exception handler without adding project bloat.
7//!
8//! ## Usage
9//!
10//! Show a modal dialog with title `Hello`, content `World`, warning icon, and an `OK` button (closes when clicked):
11//!
12//! ```no_run
13//! zero_dialog::show("Hello", "World", &Default::default());
14//! ```
15//!
16//! Show error icon with `OK` / `Cancel` buttons and capture user choice:
17//!
18//! ```no_run
19//! use zero_dialog::*;
20//!
21//! let title = "Fatal Error";
22//! let msg = "Required assets not found, click Ok to exit";
23//! let config = DialogConfig {
24//!     icon: IconKind::Error,
25//!     btn: ButtonKind::OkCancel,
26//! };
27//! let result = zero_dialog::show(title, msg, &config);
28//! match result {
29//!     Ok(Response::Ok) => std::process::exit(1),
30//!     Ok(Response::Cancel) => println!("Cancel"),
31//!     _ => println!("None"),
32//! }
33//! ```
34//!
35//! Suitable for use after `panic!()` to display critical errors.
36//!
37//! ```no_run
38//! use std::panic;
39//! use zero_dialog::show;
40//!
41//! fn main() {
42//!     panic::set_hook(Box::new(|_| {
43//!         let title = "Error";
44//!         let msg = "Something went wrong";
45//!         let _ = show(title, msg, &Default::default());
46//!     }));
47//!
48//!     panic!("Normal panic");
49//! }
50//! ```
51
52mod dialog;
53
54/// User response when clicking buttons
55#[derive(Debug, Clone, Copy, Eq, PartialEq)]
56pub enum Response {
57    /// Dialog closed, but button not clicked
58    None,
59    /// OK button clicked
60    Ok,
61    /// Cancel button clicked
62    Cancel,
63}
64
65/// Possible errors when attempting to show the dialog
66#[derive(Debug, Clone, Copy, Eq, PartialEq)]
67pub enum Error {
68    /// String conversion failure
69    InvalidString,
70    /// Dynamic link library (DLL) not found
71    FailedToLoadLibrary,
72    /// Required symbol not found in DLL
73    FailedToFindSymbol,
74    /// Failed to execute dialog
75    FailedToRunDialog,
76}
77
78#[derive(Debug, Clone, Copy, Eq, PartialEq)]
79pub enum IconKind {
80    Info,
81    Warning,
82    Error,
83    Question,
84}
85
86/// Dialog button layout
87#[derive(Debug, Clone, Copy, Eq, PartialEq)]
88pub enum ButtonKind {
89    /// Show OK button only
90    Ok,
91    /// Show both OK and Cancel buttons
92    OkCancel,
93}
94
95#[derive(Debug, Clone, Copy, Eq, PartialEq)]
96pub struct DialogConfig {
97    pub icon: IconKind,
98    pub btn: ButtonKind,
99}
100
101impl Default for DialogConfig {
102    fn default() -> Self {
103        Self {
104            icon: IconKind::Warning,
105            btn: ButtonKind::Ok,
106        }
107    }
108}
109
110/// Displays a modal dialog that blocks the calling thread and waits for user input.
111///
112/// Allows configuration of the dialog icon and button layout (default: Warning icon with OK button).
113/// Use `Default::default()` if no custom configuration is needed.
114pub fn show(title: &str, message: &str, config: &DialogConfig) -> Result<Response, Error> {
115    #[cfg(target_os = "windows")]
116    {
117        dialog::os::win32_show_dialog(title, message, config.icon, config.btn)
118    }
119
120    #[cfg(target_os = "linux")]
121    {
122        dialog::os::gtk3_show_dialog(title, message, config.icon, config.btn)
123    }
124}