guts_collaboration/
label.rs

1//! Label types for categorizing issues and pull requests.
2
3use serde::{Deserialize, Serialize};
4
5/// A label that can be applied to issues and pull requests.
6#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
7pub struct Label {
8    /// Label name (e.g., "bug", "enhancement", "documentation").
9    pub name: String,
10    /// Label color in hex format (e.g., "ff0000" for red).
11    pub color: String,
12    /// Optional description of the label.
13    pub description: Option<String>,
14}
15
16impl Label {
17    /// Creates a new label.
18    pub fn new(name: impl Into<String>, color: impl Into<String>) -> Self {
19        Self {
20            name: name.into(),
21            color: color.into(),
22            description: None,
23        }
24    }
25
26    /// Creates a new label with a description.
27    pub fn with_description(mut self, description: impl Into<String>) -> Self {
28        self.description = Some(description.into());
29        self
30    }
31}
32
33/// Predefined labels for common use cases.
34impl Label {
35    /// Bug label.
36    pub fn bug() -> Self {
37        Self::new("bug", "d73a4a").with_description("Something isn't working")
38    }
39
40    /// Enhancement label.
41    pub fn enhancement() -> Self {
42        Self::new("enhancement", "a2eeef").with_description("New feature or request")
43    }
44
45    /// Documentation label.
46    pub fn documentation() -> Self {
47        Self::new("documentation", "0075ca")
48            .with_description("Improvements or additions to documentation")
49    }
50
51    /// Good first issue label.
52    pub fn good_first_issue() -> Self {
53        Self::new("good first issue", "7057ff").with_description("Good for newcomers")
54    }
55
56    /// Help wanted label.
57    pub fn help_wanted() -> Self {
58        Self::new("help wanted", "008672").with_description("Extra attention is needed")
59    }
60
61    /// Invalid label.
62    pub fn invalid() -> Self {
63        Self::new("invalid", "e4e669").with_description("This doesn't seem right")
64    }
65
66    /// Question label.
67    pub fn question() -> Self {
68        Self::new("question", "d876e3").with_description("Further information is requested")
69    }
70
71    /// Wontfix label.
72    pub fn wontfix() -> Self {
73        Self::new("wontfix", "ffffff").with_description("This will not be worked on")
74    }
75}
76
77#[cfg(test)]
78mod tests {
79    use super::*;
80
81    #[test]
82    fn test_label_creation() {
83        let label = Label::new("test", "ff0000").with_description("A test label");
84        assert_eq!(label.name, "test");
85        assert_eq!(label.color, "ff0000");
86        assert_eq!(label.description, Some("A test label".to_string()));
87    }
88
89    #[test]
90    fn test_predefined_labels() {
91        let bug = Label::bug();
92        assert_eq!(bug.name, "bug");
93        assert_eq!(bug.color, "d73a4a");
94        assert!(bug.description.is_some());
95
96        let enhancement = Label::enhancement();
97        assert_eq!(enhancement.name, "enhancement");
98    }
99}