tempo_cli/models/
tag.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
5pub struct Tag {
6    pub id: Option<i64>,
7    pub name: String,
8    pub color: Option<String>,
9    pub description: Option<String>,
10    pub created_at: DateTime<Utc>,
11}
12
13impl Tag {
14    pub fn new(name: String) -> Self {
15        Self {
16            id: None,
17            name: name.trim().to_lowercase(),
18            color: None,
19            description: None,
20            created_at: Utc::now(),
21        }
22    }
23
24    pub fn with_color(mut self, color: String) -> Self {
25        self.color = Some(color);
26        self
27    }
28
29    pub fn with_description(mut self, description: String) -> Self {
30        self.description = Some(description);
31        self
32    }
33
34    pub fn validate(&self) -> anyhow::Result<()> {
35        if self.name.is_empty() {
36            return Err(anyhow::anyhow!("Tag name cannot be empty"));
37        }
38
39        if self.name != self.name.trim().to_lowercase() {
40            return Err(anyhow::anyhow!("Tag name must be lowercase and trimmed"));
41        }
42
43        if self.name.contains(char::is_whitespace) {
44            return Err(anyhow::anyhow!("Tag name cannot contain whitespace"));
45        }
46
47        Ok(())
48    }
49}