1use serde::{Deserialize, Serialize};
2use std::fmt;
3use uuid::Uuid;
4
5const MXR_NAMESPACE: Uuid = Uuid::from_bytes([
7 0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8,
8]);
9
10macro_rules! typed_id {
11 ($name:ident) => {
12 #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
13 #[serde(transparent)]
14 pub struct $name(pub Uuid);
15
16 impl $name {
17 pub fn new() -> Self {
18 Self(Uuid::now_v7())
19 }
20
21 pub fn from_uuid(uuid: Uuid) -> Self {
22 Self(uuid)
23 }
24
25 pub fn as_uuid(&self) -> &Uuid {
26 &self.0
27 }
28
29 pub fn as_str(&self) -> String {
30 self.0.to_string()
31 }
32
33 pub fn from_provider_id(provider: &str, id: &str) -> Self {
34 let input = format!("{provider}:{id}");
35 Self(Uuid::new_v5(&MXR_NAMESPACE, input.as_bytes()))
36 }
37 }
38
39 impl fmt::Display for $name {
40 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41 write!(f, "{}", self.0)
42 }
43 }
44
45 impl Default for $name {
46 fn default() -> Self {
47 Self::new()
48 }
49 }
50 };
51}
52
53typed_id!(AccountId);
54typed_id!(MessageId);
55typed_id!(ThreadId);
56typed_id!(LabelId);
57typed_id!(DraftId);
58typed_id!(AttachmentId);
59typed_id!(SavedSearchId);
60typed_id!(RuleId);