use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::fmt;
use std::str::FromStr;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Event {
pub id: i64,
pub issue_id: String,
pub event_type: EventType,
pub actor: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub old_value: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub new_value: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub comment: Option<String>,
pub created_at: DateTime<Utc>,
}
impl Event {
pub fn new(
id: i64,
issue_id: impl Into<String>,
event_type: EventType,
actor: impl Into<String>,
) -> Self {
Self {
id,
issue_id: issue_id.into(),
event_type,
actor: actor.into(),
old_value: None,
new_value: None,
comment: None,
created_at: Utc::now(),
}
}
pub fn with_change(
mut self,
old_value: Option<String>,
new_value: Option<String>,
) -> Self {
self.old_value = old_value;
self.new_value = new_value;
self
}
pub fn with_comment(mut self, comment: impl Into<String>) -> Self {
self.comment = Some(comment.into());
self
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum EventType {
Created,
Updated,
StatusChanged,
Commented,
Closed,
Reopened,
DependencyAdded,
DependencyRemoved,
LabelAdded,
LabelRemoved,
Compacted,
}
impl EventType {
pub fn as_str(&self) -> &'static str {
match self {
EventType::Created => "created",
EventType::Updated => "updated",
EventType::StatusChanged => "status_changed",
EventType::Commented => "commented",
EventType::Closed => "closed",
EventType::Reopened => "reopened",
EventType::DependencyAdded => "dependency_added",
EventType::DependencyRemoved => "dependency_removed",
EventType::LabelAdded => "label_added",
EventType::LabelRemoved => "label_removed",
EventType::Compacted => "compacted",
}
}
}
impl fmt::Display for EventType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_str())
}
}
impl FromStr for EventType {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"created" => Ok(EventType::Created),
"updated" => Ok(EventType::Updated),
"status_changed" => Ok(EventType::StatusChanged),
"commented" => Ok(EventType::Commented),
"closed" => Ok(EventType::Closed),
"reopened" => Ok(EventType::Reopened),
"dependency_added" => Ok(EventType::DependencyAdded),
"dependency_removed" => Ok(EventType::DependencyRemoved),
"label_added" => Ok(EventType::LabelAdded),
"label_removed" => Ok(EventType::LabelRemoved),
"compacted" => Ok(EventType::Compacted),
_ => Err(format!("unknown event type: {}", s)),
}
}
}