Skip to content

Commit 36f6b6b

Browse files
authored
feat: better error handling (#29)
1 parent 8e4e359 commit 36f6b6b

File tree

4 files changed

+45
-29
lines changed

4 files changed

+45
-29
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
/target/
22
**/*.rs.bk
33
Cargo.lock
4+
/.idea

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ default-target = "x86_64-pc-windows-msvc"
1919

2020
[dependencies]
2121
quick-xml = "0.31"
22+
thiserror = "1.0"
2223
windows-version = "0.1"
2324

2425
[dependencies.windows]

examples/simple.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ fn main() {
1313
.text1("(╯°□°)╯︵ ┻━┻")
1414
.sound(Some(Sound::SMS))
1515
.duration(Duration::Short)
16-
.on_activated(move |action| -> windows::core::Result<()> {
16+
.on_activated(move |action| {
1717
match action {
1818
Some(action) => println!("You've clicked {}!", action),
1919
None => println!("You've clicked me!"),

src/lib.rs

+42-28
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,21 @@ use std::fmt::Write;
4545
use std::path::Path;
4646
use std::str::FromStr;
4747

48-
pub use windows::core::{Error, Result, HSTRING};
48+
pub use windows::core::HSTRING;
4949
pub use windows::UI::Notifications::ToastNotification;
5050

51+
use thiserror::Error;
52+
53+
#[derive(Error, Debug)]
54+
pub enum Error {
55+
#[error("Windows API error: {0}")]
56+
Os(#[from] windows::core::Error),
57+
#[error("IO error: {0}")]
58+
Io(#[from] std::io::Error),
59+
}
60+
61+
pub type Result<T> = std::result::Result<T, Error>;
62+
5163
/// `ToastDismissalReason` is a struct representing the reason a toast notification was dismissed.
5264
///
5365
/// Variants:
@@ -255,7 +267,7 @@ pub enum Scenario {
255267
Default,
256268
/// This will be displayed pre-expanded and stay on the user's screen till dismissed. Audio will loop by default and will use alarm audio.
257269
Alarm,
258-
/// This will be displayed pre-expanded and stay on the user's screen till dismissed..
270+
/// This will be displayed pre-expanded and stay on the user's screen till dismissed.
259271
Reminder,
260272
/// This will be displayed pre-expanded in a special call format and stay on the user's screen till dismissed. Audio will loop by default and will use ringtone audio.
261273
IncomingCall,
@@ -264,7 +276,7 @@ pub enum Scenario {
264276
impl Toast {
265277
/// This can be used if you do not have a AppUserModelID.
266278
///
267-
/// However, the toast will erroniously report its origin as powershell.
279+
/// However, the toast will erroneously report its origin as powershell.
268280
pub const POWERSHELL_APP_ID: &'static str = "{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\
269281
\\WindowsPowerShell\\v1.0\\powershell.exe";
270282
/// Constructor for the toast builder.
@@ -372,7 +384,7 @@ impl Toast {
372384
);
373385
self
374386
} else {
375-
// Win81 rejects the above xml so we fallback to a simpler call
387+
// Win81 rejects the above xml, so we fall back to a simpler call
376388
self.image(source, alt_text)
377389
}
378390
}
@@ -390,7 +402,7 @@ impl Toast {
390402
);
391403
self
392404
} else {
393-
// win81 rejects the above xml so we fallback to a simpler call
405+
// win81 rejects the above xml, so we fall back to a simpler call
394406
self.image(source, alt_text)
395407
}
396408
}
@@ -436,7 +448,7 @@ impl Toast {
436448

437449
/// Adds a button to the notification
438450
/// `content` is the text of the button.
439-
/// `action` will be send as an argument [on_activated](Self::on_activated) when the button is clicked.
451+
/// `action` will be sent as an argument [on_activated](Self::on_activated) when the button is clicked.
440452
pub fn add_button(mut self, content: &str, action: &str) -> Toast {
441453
self.buttons.push(Button {
442454
content: content.to_owned(),
@@ -447,12 +459,13 @@ impl Toast {
447459

448460
// HACK: f is static so that we know the function is valid to call.
449461
// this would be nice to remove at some point
450-
pub fn on_activated<F: FnMut(Option<String>) -> Result<()> + Send + 'static>(
451-
mut self,
452-
mut f: F,
453-
) -> Self {
462+
pub fn on_activated<F>(mut self, mut f: F) -> Self
463+
where
464+
F: FnMut(Option<String>) -> Result<()> + Send + 'static,
465+
{
454466
self.on_activated = Some(TypedEventHandler::new(move |_, insp| {
455-
f(Self::get_activated_action(insp))
467+
let _ = f(Self::get_activated_action(insp));
468+
Ok(())
456469
}));
457470
self
458471
}
@@ -492,12 +505,13 @@ impl Toast {
492505
/// Ok(())
493506
/// }).show().expect("notification failed");
494507
/// ```
495-
pub fn on_dismissed<F: Fn(Option<ToastDismissalReason>) -> Result<()> + Send + 'static>(
496-
mut self,
497-
f: F,
498-
) -> Self {
508+
pub fn on_dismissed<F>(mut self, f: F) -> Self
509+
where
510+
F: Fn(Option<ToastDismissalReason>) -> Result<()> + Send + 'static,
511+
{
499512
self.on_dismissed = Some(TypedEventHandler::new(move |_, args| {
500-
f(Self::get_dismissed_reason(args))
513+
let _ = f(Self::get_dismissed_reason(args));
514+
Ok(())
501515
}));
502516
self
503517
}
@@ -513,7 +527,7 @@ impl Toast {
513527
None
514528
}
515529

516-
fn create_template(&self) -> windows::core::Result<ToastNotification> {
530+
fn create_template(&self) -> Result<ToastNotification> {
517531
//using this to get an instance of XmlDocument
518532
let toast_xml = XmlDocument::new()?;
519533

@@ -542,16 +556,16 @@ impl Toast {
542556
}
543557

544558
toast_xml.LoadXml(&HSTRING::from(format!(
545-
"<toast {} {}>
546-
<visual>
547-
<binding template=\"{}\">
559+
r#"<toast {} {}>
560+
<visual>
561+
<binding template="{}">
548562
{}
549563
{}{}{}
550-
</binding>
551-
</visual>
552-
{}
553-
{}
554-
</toast>",
564+
</binding>
565+
</visual>
566+
{}
567+
{}
568+
</toast>"#,
555569
self.duration,
556570
self.scenario,
557571
template_binding,
@@ -564,11 +578,11 @@ impl Toast {
564578
)))?;
565579

566580
// Create the toast
567-
ToastNotification::CreateToastNotification(&toast_xml)
581+
ToastNotification::CreateToastNotification(&toast_xml).map_err(Into::into)
568582
}
569583

570584
/// Display the toast on the screen
571-
pub fn show(&self) -> windows::core::Result<()> {
585+
pub fn show(&self) -> Result<()> {
572586
let toast_template = self.create_template()?;
573587
if let Some(handler) = &self.on_activated {
574588
toast_template.Activated(handler)?;
@@ -582,7 +596,7 @@ impl Toast {
582596
ToastNotificationManager::CreateToastNotifierWithId(&HSTRING::from(&self.app_id))?;
583597

584598
// Show the toast.
585-
let result = toast_notifier.Show(&toast_template);
599+
let result = toast_notifier.Show(&toast_template).map_err(Into::into);
586600
std::thread::sleep(std::time::Duration::from_millis(10));
587601
result
588602
}

0 commit comments

Comments
 (0)