rusty_beads/types/
event.rs1use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5use std::fmt;
6use std::str::FromStr;
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct Event {
11 pub id: i64,
13 pub issue_id: String,
15 pub event_type: EventType,
17 pub actor: String,
19 #[serde(skip_serializing_if = "Option::is_none")]
21 pub old_value: Option<String>,
22 #[serde(skip_serializing_if = "Option::is_none")]
24 pub new_value: Option<String>,
25 #[serde(skip_serializing_if = "Option::is_none")]
27 pub comment: Option<String>,
28 pub created_at: DateTime<Utc>,
30}
31
32impl Event {
33 pub fn new(
35 id: i64,
36 issue_id: impl Into<String>,
37 event_type: EventType,
38 actor: impl Into<String>,
39 ) -> Self {
40 Self {
41 id,
42 issue_id: issue_id.into(),
43 event_type,
44 actor: actor.into(),
45 old_value: None,
46 new_value: None,
47 comment: None,
48 created_at: Utc::now(),
49 }
50 }
51
52 pub fn with_change(
54 mut self,
55 old_value: Option<String>,
56 new_value: Option<String>,
57 ) -> Self {
58 self.old_value = old_value;
59 self.new_value = new_value;
60 self
61 }
62
63 pub fn with_comment(mut self, comment: impl Into<String>) -> Self {
65 self.comment = Some(comment.into());
66 self
67 }
68}
69
70#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
72#[serde(rename_all = "snake_case")]
73pub enum EventType {
74 Created,
76 Updated,
78 StatusChanged,
80 Commented,
82 Closed,
84 Reopened,
86 DependencyAdded,
88 DependencyRemoved,
90 LabelAdded,
92 LabelRemoved,
94 Compacted,
96}
97
98impl EventType {
99 pub fn as_str(&self) -> &'static str {
101 match self {
102 EventType::Created => "created",
103 EventType::Updated => "updated",
104 EventType::StatusChanged => "status_changed",
105 EventType::Commented => "commented",
106 EventType::Closed => "closed",
107 EventType::Reopened => "reopened",
108 EventType::DependencyAdded => "dependency_added",
109 EventType::DependencyRemoved => "dependency_removed",
110 EventType::LabelAdded => "label_added",
111 EventType::LabelRemoved => "label_removed",
112 EventType::Compacted => "compacted",
113 }
114 }
115}
116
117impl fmt::Display for EventType {
118 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119 write!(f, "{}", self.as_str())
120 }
121}
122
123impl FromStr for EventType {
124 type Err = String;
125
126 fn from_str(s: &str) -> Result<Self, Self::Err> {
127 match s.to_lowercase().as_str() {
128 "created" => Ok(EventType::Created),
129 "updated" => Ok(EventType::Updated),
130 "status_changed" => Ok(EventType::StatusChanged),
131 "commented" => Ok(EventType::Commented),
132 "closed" => Ok(EventType::Closed),
133 "reopened" => Ok(EventType::Reopened),
134 "dependency_added" => Ok(EventType::DependencyAdded),
135 "dependency_removed" => Ok(EventType::DependencyRemoved),
136 "label_added" => Ok(EventType::LabelAdded),
137 "label_removed" => Ok(EventType::LabelRemoved),
138 "compacted" => Ok(EventType::Compacted),
139 _ => Err(format!("unknown event type: {}", s)),
140 }
141 }
142}