1use serde::{Deserialize, Serialize};
4use std::fmt;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
8#[serde(rename_all = "lowercase")]
9pub enum Namespace {
10 #[default]
12 Decisions,
13 Patterns,
15 Learnings,
17 Context,
19 #[serde(alias = "techdebt", alias = "tech_debt")]
21 #[serde(rename = "tech-debt")]
22 TechDebt,
23 Blockers,
25 Progress,
27 Apis,
29 Config,
31 Security,
33 Performance,
35 Testing,
37 Help,
39}
40
41impl Namespace {
42 #[must_use]
44 pub const fn all() -> &'static [Self] {
45 &[
46 Self::Decisions,
47 Self::Patterns,
48 Self::Learnings,
49 Self::Context,
50 Self::TechDebt,
51 Self::Blockers,
52 Self::Progress,
53 Self::Apis,
54 Self::Config,
55 Self::Security,
56 Self::Performance,
57 Self::Testing,
58 Self::Help,
59 ]
60 }
61
62 #[must_use]
64 pub const fn user_namespaces() -> &'static [Self] {
65 &[
66 Self::Decisions,
67 Self::Patterns,
68 Self::Learnings,
69 Self::Context,
70 Self::TechDebt,
71 Self::Blockers,
72 Self::Progress,
73 Self::Apis,
74 Self::Config,
75 Self::Security,
76 Self::Performance,
77 Self::Testing,
78 ]
79 }
80
81 #[must_use]
83 pub const fn as_str(&self) -> &'static str {
84 match self {
85 Self::Decisions => "decisions",
86 Self::Patterns => "patterns",
87 Self::Learnings => "learnings",
88 Self::Context => "context",
89 Self::TechDebt => "tech-debt",
90 Self::Blockers => "blockers",
91 Self::Progress => "progress",
92 Self::Apis => "apis",
93 Self::Config => "config",
94 Self::Security => "security",
95 Self::Performance => "performance",
96 Self::Testing => "testing",
97 Self::Help => "help",
98 }
99 }
100
101 #[must_use]
103 pub const fn is_system(&self) -> bool {
104 matches!(self, Self::Help)
105 }
106
107 #[must_use]
109 pub fn parse(s: &str) -> Option<Self> {
110 match s.to_lowercase().as_str() {
111 "decisions" => Some(Self::Decisions),
112 "patterns" => Some(Self::Patterns),
113 "learnings" => Some(Self::Learnings),
114 "context" => Some(Self::Context),
115 "tech-debt" | "techdebt" | "tech_debt" => Some(Self::TechDebt),
116 "blockers" => Some(Self::Blockers),
117 "progress" => Some(Self::Progress),
118 "apis" => Some(Self::Apis),
119 "config" => Some(Self::Config),
120 "security" => Some(Self::Security),
121 "performance" => Some(Self::Performance),
122 "testing" => Some(Self::Testing),
123 "help" => Some(Self::Help),
124 _ => None,
125 }
126 }
127}
128
129impl fmt::Display for Namespace {
130 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
131 write!(f, "{}", self.as_str())
132 }
133}
134
135#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
137pub struct Domain {
138 pub organization: Option<String>,
140 pub project: Option<String>,
142 pub repository: Option<String>,
144}
145
146impl Domain {
147 #[must_use]
149 pub const fn new() -> Self {
150 Self {
151 organization: None,
152 project: None,
153 repository: None,
154 }
155 }
156
157 #[must_use]
159 pub fn for_repository(org: impl Into<String>, repo: impl Into<String>) -> Self {
160 Self {
161 organization: Some(org.into()),
162 project: None,
163 repository: Some(repo.into()),
164 }
165 }
166
167 #[must_use]
169 pub const fn is_global(&self) -> bool {
170 self.organization.is_none() && self.project.is_none() && self.repository.is_none()
171 }
172
173 #[must_use]
179 pub fn to_scope_string(&self) -> String {
180 match (&self.organization, &self.repository) {
181 (Some(org), Some(repo)) => format!("{org}/{repo}"),
182 (Some(org), None) => format!("org/{org}"),
183 (None, Some(repo)) => repo.clone(),
184 (None, None) => "project".to_string(),
185 }
186 }
187}
188
189impl fmt::Display for Domain {
190 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
191 match (&self.organization, &self.project, &self.repository) {
192 (Some(org), Some(proj), Some(repo)) => write!(f, "{org}/{proj}/{repo}"),
193 (Some(org), None, Some(repo)) => write!(f, "{org}/{repo}"),
194 (Some(org), Some(proj), None) => write!(f, "{org}/{proj}"),
195 (Some(org), None, None) => write!(f, "{org}"),
196 (None, Some(proj), _) => write!(f, "{proj}"),
197 (None, None, Some(repo)) => write!(f, "{repo}"),
198 (None, None, None) => write!(f, "global"),
199 }
200 }
201}
202
203#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
205pub enum MemoryStatus {
206 #[default]
208 Active,
209 Archived,
211 Superseded,
213 Pending,
215 Deleted,
217}
218
219impl MemoryStatus {
220 #[must_use]
222 pub const fn as_str(&self) -> &'static str {
223 match self {
224 Self::Active => "active",
225 Self::Archived => "archived",
226 Self::Superseded => "superseded",
227 Self::Pending => "pending",
228 Self::Deleted => "deleted",
229 }
230 }
231}
232
233impl fmt::Display for MemoryStatus {
234 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
235 write!(f, "{}", self.as_str())
236 }
237}