toast_logger_win/notification.rs
1use crate::Result;
2
3#[cfg(doc)]
4use crate::ToastLoggerBuilder;
5
6/// A struct to own copies of parts of [`log::Record`] for buffering.
7///
8/// The [`log::Record`] has lifetime for the lower overhead,
9/// and it's not suitable to buffer them.
10/// This struct captures the data needed for longer lifetime.
11#[derive(Debug, PartialEq, Eq)]
12pub struct BufferedRecord {
13 pub level: log::Level,
14 pub args: String,
15}
16
17impl BufferedRecord {
18 pub fn new_with_formatted_args(record: &log::Record, args: &str) -> Self {
19 Self {
20 level: record.level(),
21 args: args.to_string(),
22 }
23 }
24
25 pub fn level(&self) -> log::Level {
26 self.level
27 }
28
29 pub fn args(&self) -> &str {
30 &self.args
31 }
32}
33
34/// Abstracted notification.
35///
36/// This struct is to provide a hook point before the notification is shown.
37/// Please see [`ToastLoggerBuilder::create_notification`] for
38/// how to add the hook.
39///
40/// # Underlying Implementations
41///
42/// There are two underlying implementations.
43/// * An internal implementation using the [`windows` crate].
44/// This is the default.
45/// * The [`winrt-toast` crate] implementation is
46/// enabled by the feature `winrt-toast`.
47/// This crate provides additional features and controls.
48///
49/// [`windows` crate]: https://crates.io/crates/windows
50/// [`winrt-toast` crate]: https://docs.rs/winrt-toast/latest/winrt_toast/
51pub struct Notification {
52 #[cfg(not(feature = "winrt-toast"))]
53 inner: crate::win::NotificationImpl,
54 #[cfg(feature = "winrt-toast")]
55 inner: winrt_toast::Toast,
56}
57
58impl Notification {
59 /// Construct from a string.
60 pub fn new_with_text(text: &str) -> Result<Self> {
61 Ok(Self {
62 #[cfg(not(feature = "winrt-toast"))]
63 inner: crate::win::NotificationImpl::new_with_text(text)?,
64 #[cfg(feature = "winrt-toast")]
65 inner: {
66 let mut toast = winrt_toast::Toast::new();
67 toast.text1(text);
68 toast
69 },
70 })
71 }
72
73 /// Construct from a list of [`BufferedRecord`].
74 pub fn new_with_records(records: &[BufferedRecord]) -> Result<Self> {
75 let text = records
76 .iter()
77 .map(|r| r.args.as_str())
78 .collect::<Vec<_>>()
79 .join("\n");
80 Self::new_with_text(&text)
81 }
82
83 /// Set the expirations of this notification.
84 /// Please see [`ToastNotification.ExpirationTime`].
85 ///
86 /// [`ToastNotification.ExpirationTime`]: https://learn.microsoft.com/uwp/api/windows.ui.notifications.toastnotification.expirationtime
87 pub fn expires_in(&mut self, duration: std::time::Duration) -> Result<()> {
88 #[cfg(not(feature = "winrt-toast"))]
89 self.inner.expires_in(duration)?;
90 #[cfg(feature = "winrt-toast")]
91 self.inner.expires_in(duration);
92 Ok(())
93 }
94
95 /// The inner [`winrt_toast::Toast`].
96 ///
97 /// Available only when the "`winrt-toast`" feature is enabled.
98 #[cfg(feature = "winrt-toast")]
99 // error[E0658]: `#[doc(cfg)]` is experimental
100 // https://github.com/rust-lang/rust/issues/43781
101 // #[cfg_attr(docsrs, doc(cfg(feature = "winrt-toast")))]
102 pub fn inner(&self) -> &winrt_toast::Toast {
103 &self.inner
104 }
105
106 /// The mutable inner [`winrt_toast::Toast`].
107 ///
108 /// Available only when the "`winrt-toast`" feature is enabled.
109 #[cfg(feature = "winrt-toast")]
110 // error[E0658]: `#[doc(cfg)]` is experimental
111 // https://github.com/rust-lang/rust/issues/43781
112 // #[cfg_attr(docsrs, doc(cfg(feature = "winrt-toast")))]
113 pub fn inner_mut(&mut self) -> &mut winrt_toast::Toast {
114 &mut self.inner
115 }
116}
117
118/// Abstracted notifier for the `Notification`.
119pub(crate) struct Notifier {
120 #[cfg(not(feature = "winrt-toast"))]
121 inner: crate::win::NotifierImpl,
122 #[cfg(feature = "winrt-toast")]
123 inner: winrt_toast::ToastManager,
124}
125
126impl Notifier {
127 pub fn new_with_application_id(application_id: &str) -> Result<Self> {
128 Ok(Self {
129 #[cfg(not(feature = "winrt-toast"))]
130 inner: crate::win::NotifierImpl::new_with_application_id(application_id)?,
131 #[cfg(feature = "winrt-toast")]
132 inner: winrt_toast::ToastManager::new(application_id),
133 })
134 }
135
136 pub fn show(&self, notification: &Notification) -> Result<()> {
137 self.inner.show(¬ification.inner)?;
138 Ok(())
139 }
140}