1use serde::{Deserialize, Serialize};
2use std::fmt;
3
4#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
6pub enum Namespace {
7 Comments,
8 Review,
9 Todos,
10 Custom(String),
11}
12
13impl Namespace {
14 pub fn ref_path(&self) -> String {
16 match self {
17 Namespace::Comments => "refs/notes/comments".to_string(),
18 Namespace::Review => "refs/notes/review".to_string(),
19 Namespace::Todos => "refs/notes/todos".to_string(),
20 Namespace::Custom(name) => format!("refs/notes/{}", name),
21 }
22 }
23
24 #[allow(clippy::should_implement_trait)]
26 pub fn from_str(s: &str) -> Self {
27 let stripped = s.strip_prefix("refs/notes/").unwrap_or(s);
29 match stripped {
30 "comments" => Namespace::Comments,
31 "review" => Namespace::Review,
32 "todos" => Namespace::Todos,
33 other => Namespace::Custom(other.to_string()),
34 }
35 }
36}
37
38#[cfg(test)]
39mod tests {
40 use super::*;
41
42 #[test]
43 fn test_from_str_builtin_without_prefix() {
44 assert_eq!(Namespace::from_str("comments"), Namespace::Comments);
45 assert_eq!(Namespace::from_str("review"), Namespace::Review);
46 assert_eq!(Namespace::from_str("todos"), Namespace::Todos);
47 }
48
49 #[test]
50 fn test_from_str_builtin_with_prefix() {
51 assert_eq!(Namespace::from_str("refs/notes/comments"), Namespace::Comments);
52 assert_eq!(Namespace::from_str("refs/notes/review"), Namespace::Review);
53 assert_eq!(Namespace::from_str("refs/notes/todos"), Namespace::Todos);
54 }
55
56 #[test]
57 fn test_from_str_custom() {
58 assert_eq!(
59 Namespace::from_str("bugs"),
60 Namespace::Custom("bugs".to_string())
61 );
62 assert_eq!(
63 Namespace::from_str("refs/notes/bugs"),
64 Namespace::Custom("bugs".to_string())
65 );
66 }
67
68 #[test]
69 fn test_ref_path_and_display() {
70 let cases = vec![
71 (Namespace::Comments, "refs/notes/comments", "comments"),
72 (Namespace::Review, "refs/notes/review", "review"),
73 (Namespace::Todos, "refs/notes/todos", "todos"),
74 (Namespace::Custom("my-notes".to_string()), "refs/notes/my-notes", "my-notes"),
75 ];
76
77 for (ns, expected_ref, expected_display) in cases {
78 assert_eq!(ns.ref_path(), expected_ref);
79 assert_eq!(ns.to_string(), expected_display);
80 assert_eq!(Namespace::from_str(expected_ref), ns);
81 assert_eq!(Namespace::from_str(expected_display), ns);
82 }
83 }
84}
85
86impl fmt::Display for Namespace {
87 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88 match self {
89 Namespace::Comments => write!(f, "comments"),
90 Namespace::Review => write!(f, "review"),
91 Namespace::Todos => write!(f, "todos"),
92 Namespace::Custom(name) => write!(f, "{}", name),
93 }
94 }
95}