use serde::{Deserialize, Serialize};
use std::fmt;
use std::str::FromStr;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
#[serde(rename_all = "snake_case")]
pub enum IssueType {
Bug,
Feature,
#[default]
Task,
Epic,
Chore,
Message,
Molecule,
Gate,
Agent,
Role,
Rig,
Convoy,
Event,
MergeRequest,
Slot,
}
impl IssueType {
pub fn all() -> &'static [IssueType] {
&[
IssueType::Bug,
IssueType::Feature,
IssueType::Task,
IssueType::Epic,
IssueType::Chore,
IssueType::Message,
IssueType::Molecule,
IssueType::Gate,
IssueType::Agent,
IssueType::Role,
IssueType::Rig,
IssueType::Convoy,
IssueType::Event,
IssueType::MergeRequest,
IssueType::Slot,
]
}
pub fn as_str(&self) -> &'static str {
match self {
IssueType::Bug => "bug",
IssueType::Feature => "feature",
IssueType::Task => "task",
IssueType::Epic => "epic",
IssueType::Chore => "chore",
IssueType::Message => "message",
IssueType::Molecule => "molecule",
IssueType::Gate => "gate",
IssueType::Agent => "agent",
IssueType::Role => "role",
IssueType::Rig => "rig",
IssueType::Convoy => "convoy",
IssueType::Event => "event",
IssueType::MergeRequest => "merge_request",
IssueType::Slot => "slot",
}
}
pub fn is_container(&self) -> bool {
matches!(self, IssueType::Epic | IssueType::Molecule | IssueType::Convoy)
}
pub fn is_agent_type(&self) -> bool {
matches!(self, IssueType::Agent | IssueType::Role | IssueType::Rig)
}
}
impl fmt::Display for IssueType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_str())
}
}
impl FromStr for IssueType {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"bug" => Ok(IssueType::Bug),
"feature" => Ok(IssueType::Feature),
"task" => Ok(IssueType::Task),
"epic" => Ok(IssueType::Epic),
"chore" => Ok(IssueType::Chore),
"message" => Ok(IssueType::Message),
"molecule" => Ok(IssueType::Molecule),
"gate" => Ok(IssueType::Gate),
"agent" => Ok(IssueType::Agent),
"role" => Ok(IssueType::Role),
"rig" => Ok(IssueType::Rig),
"convoy" => Ok(IssueType::Convoy),
"event" => Ok(IssueType::Event),
"merge_request" | "merge-request" | "mergerequest" => Ok(IssueType::MergeRequest),
"slot" => Ok(IssueType::Slot),
_ => Err(format!("unknown issue type: {}", s)),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_issue_type_roundtrip() {
for issue_type in IssueType::all() {
let s = issue_type.as_str();
let parsed: IssueType = s.parse().unwrap();
assert_eq!(*issue_type, parsed);
}
}
}