use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct MenuItemId(String);
impl MenuItemId {
pub fn new(id: impl Into<String>) -> Self {
Self(id.into())
}
pub fn as_str(&self) -> &str {
&self.0
}
pub fn into_string(self) -> String {
self.0
}
}
impl<S: Into<String>> From<S> for MenuItemId {
fn from(s: S) -> Self {
Self(s.into())
}
}
impl fmt::Display for MenuItemId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Debug, Clone)]
pub enum TrayEvent {
Click,
DoubleClick,
RightClick,
MenuItemClicked(MenuItemId),
Ready,
Destroyed,
}
impl TrayEvent {
pub fn is_menu_event(&self) -> bool {
matches!(self, TrayEvent::MenuItemClicked(_))
}
pub fn is_click_event(&self) -> bool {
matches!(
self,
TrayEvent::Click | TrayEvent::DoubleClick | TrayEvent::RightClick
)
}
pub fn menu_item_id(&self) -> Option<&MenuItemId> {
match self {
TrayEvent::MenuItemClicked(id) => Some(id),
_ => None,
}
}
}
impl fmt::Display for TrayEvent {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TrayEvent::Click => write!(f, "Click"),
TrayEvent::DoubleClick => write!(f, "DoubleClick"),
TrayEvent::RightClick => write!(f, "RightClick"),
TrayEvent::MenuItemClicked(id) => write!(f, "MenuItemClicked({})", id),
TrayEvent::Ready => write!(f, "Ready"),
TrayEvent::Destroyed => write!(f, "Destroyed"),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_menu_item_id() {
let id = MenuItemId::new("test_id");
assert_eq!(id.as_str(), "test_id");
assert_eq!(id.to_string(), "test_id");
}
#[test]
fn test_menu_item_id_from() {
let id1: MenuItemId = "from_str".into();
let id2: MenuItemId = String::from("from_string").into();
assert_eq!(id1.as_str(), "from_str");
assert_eq!(id2.as_str(), "from_string");
}
#[test]
fn test_event_is_menu() {
assert!(TrayEvent::MenuItemClicked("id".into()).is_menu_event());
assert!(!TrayEvent::Click.is_menu_event());
assert!(!TrayEvent::Ready.is_menu_event());
}
#[test]
fn test_event_is_click() {
assert!(TrayEvent::Click.is_click_event());
assert!(TrayEvent::DoubleClick.is_click_event());
assert!(TrayEvent::RightClick.is_click_event());
assert!(!TrayEvent::Ready.is_click_event());
assert!(!TrayEvent::MenuItemClicked("id".into()).is_click_event());
}
#[test]
fn test_event_menu_item_id() {
let event = TrayEvent::MenuItemClicked("test".into());
assert_eq!(event.menu_item_id().map(|id| id.as_str()), Some("test"));
let event = TrayEvent::Click;
assert!(event.menu_item_id().is_none());
}
#[test]
fn test_event_display() {
assert_eq!(TrayEvent::Click.to_string(), "Click");
assert_eq!(TrayEvent::Ready.to_string(), "Ready");
assert_eq!(
TrayEvent::MenuItemClicked("exit".into()).to_string(),
"MenuItemClicked(exit)"
);
}
}