1use std::{
2 cell::LazyCell,
3 collections::{HashMap, HashSet},
4 sync::{LazyLock, Mutex, OnceLock},
5};
6
7trait CheckUuid {
8 fn id(&self) -> &uuid::Uuid;
9 fn to_string(&self) -> String;
10}
11static KNOWN_UUIDS: OnceLock<Mutex<HashMap<uuid::Uuid, Vec<Box<dyn CheckUuid + Send + Sync>>>>> =
12 OnceLock::new();
13
14fn check_uuid(id: impl CheckUuid + Send + Sync + 'static) {
15 let mut map = KNOWN_UUIDS
17 .get_or_init(|| Mutex::new(HashMap::new()))
18 .lock()
19 .unwrap();
20 if let Some(existing) = map.get(id.id()) {
22 let mut types = HashSet::new();
24 for existing_id in existing {
25 types.insert(existing_id.to_string());
26 }
27
28 if types.len() > 1 {
29 log::warn!(
30 "UUIDs with different types found: {}. Already registered as: {}",
31 id.to_string(),
32 types.into_iter().collect::<Vec<_>>().join(", ")
33 );
34 }
35 }
36
37 map.entry(id.id().clone()).or_default().push(Box::new(id));
39}
40
41macro_rules! implement_uuid {
42 ($name:ident) => {
43 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
44 pub struct $name(uuid::Uuid);
45
46 impl $name {
47 pub fn new(id: uuid::Uuid) -> Self {
48 let id = Self(id);
49 check_uuid(id.clone());
50 id
51 }
52
53 pub fn from_str(s: &str) -> crate::error::Result<Self> {
54 let id = Self(uuid::Uuid::parse_str(s).inspect_err(|e| {
55 log::error!("Failed to parse UUID from byte string: {}", s);
56 })?);
57 check_uuid(id.clone());
58 Ok(id)
59 }
60
61 pub fn from_byte_str(s: &[u8]) -> crate::error::Result<Self> {
62 let s =
63 std::str::from_utf8(s).map_err(|e| crate::error::Error::UuidInvalidUtf8(e))?;
64 let id = Self(uuid::Uuid::parse_str(s).inspect_err(|e| {
65 log::error!("Failed to parse UUID from byte string: {}", s);
66 })?);
67 check_uuid(id.clone());
68 Ok(id)
69 }
70
71 pub fn to_simple_string(&self) -> String {
72 self.0.simple().to_string()
73 }
74
75 pub fn to_hyphenated_string(&self) -> String {
76 self.0.hyphenated().to_string()
77 }
78 }
79
80 impl std::fmt::Display for $name {
81 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82 write!(f, "{}({})", stringify!($name), self.0.to_string())
83 }
84 }
85
86 impl<'de> serde::Deserialize<'de> for $name {
87 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
88 where
89 D: serde::Deserializer<'de>,
90 {
91 let id: uuid::Uuid = serde::Deserialize::deserialize(deserializer)?;
92 Ok(Self(id))
93 }
94 }
95
96 impl CheckUuid for $name {
97 fn id(&self) -> &uuid::Uuid {
98 &self.0
99 }
100
101 fn to_string(&self) -> String {
102 format!("{}({})", stringify!($name), self.0.to_string())
103 }
104 }
105 };
106}
107
108implement_uuid!(NoteUuid);
109implement_uuid!(VirtualPageUuid);
110implement_uuid!(VirtualDocUuid);
111implement_uuid!(StrokeUuid);
112implement_uuid!(PageUuid);
113implement_uuid!(PageModelUuid);
114implement_uuid!(PenUuid);
115implement_uuid!(ShapeGroupUuid);
116implement_uuid!(PointsUuid);
117
118#[derive(Debug, Clone, PartialEq, Eq)]
119pub enum PenId {
120 Uuid(PenUuid),
121 Id(u32),
122}
123
124impl PenId {
125 pub fn from_uuid(uuid: PenUuid) -> Self {
126 Self::Uuid(uuid)
127 }
128
129 pub fn from_id(id: u32) -> Self {
130 Self::Id(id)
131 }
132}
133
134impl std::fmt::Display for PenId {
135 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
136 match self {
137 Self::Uuid(uuid) => write!(f, "{}", uuid),
138 Self::Id(id) => write!(f, "PenId({})", id),
139 }
140 }
141}
142
143impl<'de> serde::Deserialize<'de> for PenId {
144 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
145 where
146 D: serde::Deserializer<'de>,
147 {
148 let id: String = serde::Deserialize::deserialize(deserializer)?;
149 if id.len() == 32 {
150 let uuid = PenUuid::from_str(&id).map_err(serde::de::Error::custom)?;
152 return Ok(Self::from_uuid(uuid));
153 }
154 Ok(Self::from_id(id.parse().map_err(serde::de::Error::custom)?))
155 }
156}
157
158#[derive(Debug, Clone, Copy, PartialEq, Eq)]
159pub struct LayerId(u32);
160
161impl LayerId {
162 pub fn new(id: u32) -> Self {
163 Self(id)
164 }
165}
166
167impl std::fmt::Display for LayerId {
168 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
169 write!(f, "LayerId({})", self.0)
170 }
171}
172
173impl<'de> serde::Deserialize<'de> for LayerId {
174 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
175 where
176 D: serde::Deserializer<'de>,
177 {
178 let id: u32 = serde::Deserialize::deserialize(deserializer)?;
179 Ok(Self(id))
180 }
181}