Skip to main content

synaps_cli/events/
types.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4use uuid::Uuid;
5
6#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
7pub enum Severity {
8    Low,
9    Medium,
10    High,
11    Critical,
12}
13
14impl Severity {
15    pub fn as_str(&self) -> &str {
16        match self {
17            Severity::Low => "low",
18            Severity::Medium => "medium",
19            Severity::High => "high",
20            Severity::Critical => "critical",
21        }
22    }
23
24    pub fn from_str(s: &str) -> Self {
25        match s.to_lowercase().as_str() {
26            "low" => Severity::Low,
27            "high" => Severity::High,
28            "critical" => Severity::Critical,
29            _ => Severity::Medium,
30        }
31    }
32}
33
34#[derive(Debug, Clone, Serialize, Deserialize)]
35pub struct EventSource {
36    pub source_type: String,
37    pub name: String,
38    pub callback: Option<String>,
39}
40
41#[derive(Debug, Clone, Serialize, Deserialize)]
42pub struct EventChannel {
43    pub id: String,
44    pub name: String,
45}
46
47#[derive(Debug, Clone, Serialize, Deserialize)]
48pub struct EventSender {
49    pub id: String,
50    pub name: String,
51    pub sender_type: String,
52}
53
54#[derive(Debug, Clone, Serialize, Deserialize)]
55pub struct EventContent {
56    pub text: String,
57    pub content_type: String,
58    pub severity: Option<Severity>,
59    pub data: Option<Value>,
60}
61
62#[derive(Debug, Clone, Serialize, Deserialize)]
63pub struct Event {
64    pub id: String,
65    pub timestamp: DateTime<Utc>,
66    pub source: EventSource,
67    pub channel: Option<EventChannel>,
68    pub sender: Option<EventSender>,
69    pub content: EventContent,
70    pub expects_response: bool,
71    pub reply_to: Option<String>,
72}
73
74impl Event {
75    /// Create a simple event from minimal params (for CLI / quick use).
76    pub fn simple(source_type: &str, text: &str, severity: Option<Severity>) -> Self {
77        Event {
78            id: Uuid::new_v4().to_string(),
79            timestamp: Utc::now(),
80            source: EventSource {
81                source_type: source_type.to_string(),
82                name: source_type.to_string(),
83                callback: None,
84            },
85            channel: None,
86            sender: None,
87            content: EventContent {
88                text: text.to_string(),
89                content_type: "message".to_string(),
90                severity,
91                data: None,
92            },
93            expects_response: false,
94            reply_to: None,
95        }
96    }
97}
98
99#[cfg(test)]
100mod tests {
101    use super::*;
102
103    #[test]
104    fn severity_ordering() {
105        assert!(Severity::Low < Severity::Medium);
106        assert!(Severity::Medium < Severity::High);
107        assert!(Severity::High < Severity::Critical);
108    }
109
110    #[test]
111    fn severity_str_roundtrip() {
112        for s in [Severity::Low, Severity::Medium, Severity::High, Severity::Critical] {
113            assert_eq!(Severity::from_str(s.as_str()), s);
114        }
115        assert_eq!(Severity::from_str("garbage"), Severity::Medium);
116    }
117
118    #[test]
119    fn event_simple_defaults() {
120        let e = Event::simple("cli", "hello", Some(Severity::High));
121        assert_eq!(e.source.source_type, "cli");
122        assert_eq!(e.content.text, "hello");
123        assert_eq!(e.content.severity, Some(Severity::High));
124        assert!(!e.expects_response);
125        assert!(e.channel.is_none());
126    }
127
128    #[test]
129    fn event_serde_roundtrip() {
130        let e = Event::simple("discord", "yo", Some(Severity::Critical));
131        let json = serde_json::to_string(&e).unwrap();
132        let back: Event = serde_json::from_str(&json).unwrap();
133        assert_eq!(back.id, e.id);
134        assert_eq!(back.content.text, "yo");
135        assert_eq!(back.content.severity, Some(Severity::Critical));
136    }
137}