dtz_identifier/
case_id.rs

1static PREFIX: &str = "case-";
2
3#[derive(Debug, Clone, PartialEq)]
4pub struct CaseId {
5    pub id: String,
6}
7
8impl Default for CaseId {
9    fn default() -> Self {
10        Self {
11            id: crate::generate_internal_id(),
12        }
13    }
14}
15
16impl std::fmt::Display for CaseId {
17    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18        f.write_str(&format!("{PREFIX}{}", self.id))
19    }
20}
21
22impl TryFrom<String> for CaseId {
23    type Error = String;
24
25    fn try_from(value: String) -> Result<Self, Self::Error> {
26        if let Some(id_str) = value.strip_prefix(PREFIX) {
27            Ok(CaseId { id: id_str.to_string() })
28        } else {
29            Err("invalid format".to_string())
30        }
31    }
32}
33
34impl TryFrom<&str> for CaseId {
35    type Error = String;
36
37    fn try_from(value: &str) -> Result<Self, Self::Error> {
38        if let Some(id_str) = value.strip_prefix(PREFIX) {
39            Ok(CaseId { id: id_str.to_string() })
40        } else {
41            Err("invalid format".to_string())
42        }
43    }
44}
45
46impl<'de> serde::Deserialize<'de> for CaseId {
47    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
48    where
49        D: serde::Deserializer<'de>,
50    {
51        struct CaseIdVisitor;
52
53        impl<'de> serde::de::Visitor<'de> for CaseIdVisitor {
54            type Value = CaseId;
55
56            fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
57                formatter.write_str("a string starting with '")?;
58                formatter.write_str(PREFIX)?;
59                formatter.write_str("' followed by a 8-character alphanumeric string")
60            }
61
62            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
63            where
64                E: serde::de::Error,
65            {
66                if let Some(uuid_str) = value.strip_prefix(PREFIX) {
67                    let uuid = uuid::Uuid::parse_str(uuid_str).map_err(E::custom)?;
68                    Ok(CaseId { id: uuid.to_string() })
69                } else {
70                    Err(E::custom("invalid format"))
71                }
72            }
73        }
74
75        deserializer.deserialize_str(CaseIdVisitor)
76    }
77}
78
79impl serde::Serialize for CaseId {
80    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
81    where
82        S: serde::Serializer,
83    {
84        serializer.serialize_str(&self.to_string())
85    }
86}
87
88#[test]
89fn test_from() {
90    let ctx = CaseId::try_from("case-12345678").unwrap();
91    assert_eq!(ctx.id, "12345678");
92}