origin_platform/
notifications.rs1use async_trait::async_trait;
2use origin_domain::Result;
3use serde::{Deserialize, Serialize};
4use std::fmt::Debug;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
7#[serde(rename_all = "snake_case")]
8pub enum Urgency {
9 Low,
10 #[default]
11 Normal,
12 Critical,
13}
14
15#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
16pub struct Notification {
17 pub title: String,
18 pub body: Option<String>,
19 pub urgency: Urgency,
20 pub tag: Option<String>,
23}
24
25impl Notification {
26 pub fn new(title: impl Into<String>) -> Self {
27 Self {
28 title: title.into(),
29 body: None,
30 urgency: Urgency::Normal,
31 tag: None,
32 }
33 }
34
35 pub fn with_body(mut self, body: impl Into<String>) -> Self {
36 self.body = Some(body.into());
37 self
38 }
39
40 pub fn with_urgency(mut self, urgency: Urgency) -> Self {
41 self.urgency = urgency;
42 self
43 }
44
45 pub fn with_tag(mut self, tag: impl Into<String>) -> Self {
46 self.tag = Some(tag.into());
47 self
48 }
49}
50
51#[async_trait]
56pub trait NotificationService: Debug + Send + Sync + 'static {
57 async fn notify(&self, notification: Notification) -> Result<()>;
58}
59
60#[derive(Debug, Clone, Copy, Default)]
62pub struct NoopNotificationService;
63
64#[async_trait]
65impl NotificationService for NoopNotificationService {
66 async fn notify(&self, notification: Notification) -> Result<()> {
67 tracing::debug!(title = %notification.title, "notification dropped (noop service)");
68 Ok(())
69 }
70}