winrt_toast/
toast.rs

1use std::{collections::HashMap, time::Duration};
2
3use crate::{Header, Image, Text, Action};
4
5/// Represents a Windows toast.
6///
7/// See <https://docs.microsoft.com/en-us/uwp/api/windows.ui.notifications.toastnotification>
8///
9#[derive(Debug, Clone, Default)]
10pub struct Toast {
11    pub(crate) header: Option<Header>,
12    pub(crate) text: (Option<Text>, Option<Text>, Option<Text>),
13    pub(crate) images: HashMap<u8, Image>,
14    pub(crate) tag: Option<String>,
15    pub(crate) group: Option<String>,
16    pub(crate) remote_id: Option<String>,
17    pub(crate) expires_in: Option<Duration>,
18    pub(crate) scenario: Option<Scenario>,
19    pub(crate) launch: Option<String>,
20    pub(crate) duration: Option<ToastDuration>,
21    pub(crate) actions: Vec<Action>,
22}
23
24impl Toast {
25    /// Creates an empty toast.
26    pub fn new() -> Self {
27        Self::default()
28    }
29
30    /// Add a [`Header`] to this toast.
31    pub fn header(&mut self, header: Header) -> &mut Toast {
32        self.header = header.into();
33        self
34    }
35
36    /// The first text element, usually the title.
37    ///
38    /// # Example
39    /// ```rust
40    /// # use winrt_toast::{Toast, Text};
41    /// # use winrt_toast::content::text::TextPlacement;
42    /// # let mut toast = Toast::new();
43    /// // You can use anything that is Into<String>
44    /// toast.text1("text");
45    ///
46    /// // Or you can use a `Text`
47    /// toast.text1(
48    ///     Text::new("text").with_placement(TextPlacement::Attribution)
49    /// );
50    /// ```
51    pub fn text1<T: Into<Text>>(&mut self, text: T) -> &mut Toast {
52        self.text.0 = Some(text.into());
53        self
54    }
55
56    /// The second text element, usually the body.
57    pub fn text2<T: Into<Text>>(&mut self, text: T) -> &mut Toast {
58        self.text.1 = Some(text.into());
59        self
60    }
61
62    /// The third text element, usually the body or attribution.
63    pub fn text3<T: Into<Text>>(&mut self, text: T) -> &mut Toast {
64        self.text.2 = Some(text.into());
65        self
66    }
67
68    /// Add an image with the corresponding ID to the toast.
69    ///
70    /// # ID
71    /// The image element in the toast template that this image is intended for.
72    /// If a template has only one image, then this value is 1.
73    /// The number of available image positions is based on the template definition.
74    pub fn image(&mut self, id: u8, image: Image) -> &mut Toast {
75        self.images.insert(id, image);
76        self
77    }
78
79    /// Add a new action to the toast.
80    pub fn action(&mut self, action: Action) -> &mut Toast {
81        self.actions.push(action);
82        self
83    }
84
85    /// Set the tag of this toast.
86    ///
87    /// See <https://docs.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/send-local-toast-cpp-uwp?tabs=xml#provide-a-primary-key-for-your-toast>
88    pub fn tag(&mut self, tag: impl Into<String>) -> &mut Toast {
89        self.tag = Some(tag.into());
90        self
91    }
92
93    /// Set the group of this toast.
94    ///
95    /// See <https://docs.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/send-local-toast-cpp-uwp?tabs=xml#provide-a-primary-key-for-your-toast>
96    pub fn group(&mut self, group: impl Into<String>) -> &mut Toast {
97        self.group = Some(group.into());
98        self
99    }
100
101    /// Set a remote id for the notification that enables the system to correlate
102    /// this notification with another one generated on another device.
103    pub fn remote_id(&mut self, remote_id: impl Into<String>) -> &mut Toast {
104        self.remote_id = Some(remote_id.into());
105        self
106    }
107
108    /// Set the scenario of this toast.
109    ///
110    /// The scenario adjusts a few behaviors to create a consistent and unified user experience.
111    pub fn scenario(&mut self, scenario: Scenario) -> &mut Toast {
112        self.scenario = Some(scenario);
113        self
114    }
115
116    /// A string that is passed to the application when it is activated by the toast.
117    ///
118    /// The format and contents of this string are defined by the app for its own use.
119    /// When the user taps or clicks the toast to launch its associated app,
120    ///  the launch string provides the context to the app that allows it to show the user a view relevant to the toast content,
121    /// rather than launching in its default way.
122    pub fn launch(&mut self, launch: impl Into<String>) -> &mut Toast {
123        self.launch = Some(launch.into());
124        self
125    }
126
127    /// The amount of time the toast should display.
128    pub fn duration(&mut self, duration: ToastDuration) -> &mut Toast {
129        self.duration = Some(duration);
130        self
131    }
132
133    /// Set the expiration time of this toats, starting from the moment it is shown.
134    ///
135    /// After expiration, the toast will be removed from the Notification Center.
136    pub fn expires_in(&mut self, duration: Duration) -> &mut Toast {
137        self.expires_in = Some(duration);
138        self
139    }
140}
141
142/// The scenario your toast is used for, like an alarm or reminder.
143///
144/// See [Microsoft documentation](https://docs.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/adaptive-interactive-toasts?tabs=xml#scenarios).
145#[derive(Debug, Clone)]
146pub enum Scenario {
147    /// A reminder notification. This will be displayed pre-expanded and stay on the user's screen till dismissed.
148    Reminder,
149    /// An alarm notification. This will be displayed pre-expanded and stay on the user's screen till dismissed.
150    /// Audio will loop by default and will use alarm audio.
151    Alarm,
152    /// An incoming call notification.
153    /// This will be displayed pre-expanded in a special call format and stay on the user's screen till dismissed.
154    /// Audio will loop by default and will use ringtone audio.
155    IncomingCall,
156    /// An important notification.
157    /// This allows users to have more control over what apps can send them high-priority toast notifications that can break through Focus Assist (Do not Disturb).
158    /// This can be modified in the notifications settings.
159    Urgent,
160}
161
162impl Scenario {
163    pub(crate) fn as_str(&self) -> &'static str {
164        match self {
165            Scenario::Reminder => "reminder",
166            Scenario::Alarm => "alarm",
167            Scenario::IncomingCall => "incomingCall",
168            Scenario::Urgent => "urgent",
169        }
170    }
171}
172
173/// The amount of time the toast should display
174#[derive(Debug, Clone)]
175pub enum ToastDuration {
176    /// The toast will display for a longer period of time.
177    Long,
178    /// The toast will display for a shorter period of time.
179    Short,
180}
181
182impl ToastDuration {
183    pub(crate) fn as_str(&self) -> &'static str {
184        match self {
185            ToastDuration::Long => "long",
186            ToastDuration::Short => "short",
187        }
188    }
189}