1use crate::symbol::Symbol;
2use once_cell::sync::Lazy;
4use ahash::AHashMap;
6use std::{
7 hash::Hash,
8 hash::Hasher,
9 ptr::eq as ptr_eq
10};
11
12use std::sync::Mutex;
13use serde::{Serialize, Deserialize, Serializer, Deserializer};
14use deepsize::DeepSizeOf;
15
16#[derive(PartialEq, Eq, Hash, Clone, Serialize, Deserialize, Debug, Default)]
17pub struct IdCoreNxM<const N: usize, const M: usize> {
18 pub code: Symbol<N>,
19 pub venue: Symbol<M>,
20}
21
22#[derive(Clone, Copy)]
23pub struct StaticIdNxM<const N: usize, const M: usize> {
24 pub id_ptr: *const IdCoreNxM<N, M>,
25}
26
27impl<const N: usize, const M: usize> DeepSizeOf for StaticIdNxM<N, M> {
28 fn deep_size_of_children(&self, _context: &mut deepsize::Context) -> usize {
29 0
30 }
31}
32unsafe impl<const N: usize, const M: usize> Send for StaticIdNxM<N, M> {}
34unsafe impl<const N: usize, const M: usize> Sync for StaticIdNxM<N, M> {}
35
36impl<const N: usize, const M: usize> std::fmt::Display for StaticIdNxM<N, M> {
38 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39 unsafe {
40 write!(f, "{}@{}", (*self.id_ptr).code, (*self.id_ptr).venue)
41 }
42 }
43}
44
45impl<const N: usize, const M: usize> std::fmt::Debug for StaticIdNxM<N, M> {
46 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47 unsafe {
48 write!(f, "{}@{}", (*self.id_ptr).code, (*self.id_ptr).venue)
49 }
50 }
51}
52
53impl<const N: usize, const M: usize> PartialEq for StaticIdNxM<N, M> {
54 #[inline]
55 fn eq(&self, other: &Self) -> bool {
56 ptr_eq(self.id_ptr, other.id_ptr)
57 }
58}
59
60impl<const N: usize, const M: usize> Eq for StaticIdNxM<N, M> {}
61
62impl<const N: usize, const M: usize> Hash for StaticIdNxM<N, M> {
63 #[inline]
64 fn hash<H: Hasher>(&self, state: &mut H) {
65 self.id_ptr.hash(state);
66 }
67}
68
69impl<const N: usize, const M: usize> StaticIdNxM<N, M> {
70 #[inline]
71 pub fn len(&self) -> usize {
72 unsafe { (*self.id_ptr).code.len() + (*self.id_ptr).venue.len() }
73 }
74
75 #[inline]
76 pub fn is_empty(&self) -> bool {
77 unsafe { (*self.id_ptr).code.is_empty() && (*self.id_ptr).venue.is_empty() }
78 }
79
80 #[inline]
81 pub fn upper_bound_len(&self) -> usize {
82 unsafe { (*self.id_ptr).code.upper_bound() + (*self.id_ptr).venue.upper_bound() }
83 }
84
85 #[inline]
86 #[must_use]
87 pub fn code_str(&self) -> &str {
88 unsafe { (*self.id_ptr).code.as_str() }
89 }
90
91 #[inline]
92 #[must_use]
93 pub fn venue_str(&self) -> &str {
94 unsafe { (*self.id_ptr).venue.as_str() }
95 }
96}
97
98impl<const N: usize, const M: usize> Serialize for StaticIdNxM<N, M> {
99 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
100 where
101 S: Serializer,
102 {
103 serializer.serialize_str(&self.to_string())
104 }
105}
106
107pub type IdCore16x0 = IdCoreNxM<16, 0>;
108pub type IdCore16x16 = IdCoreNxM<16, 16>;
109pub type IdCore16x32 = IdCoreNxM<16, 32>;
110pub type IdCore16x64 = IdCoreNxM<16, 64>;
111pub type IdCore32x0 = IdCoreNxM<32, 0>;
112pub type IdCore32x16 = IdCoreNxM<32, 16>;
113pub type IdCore32x32 = IdCoreNxM<32, 32>;
114pub type IdCore32x64 = IdCoreNxM<32, 64>;
115pub type IdCore64x0 = IdCoreNxM<64, 0>;
116pub type IdCore64x16 = IdCoreNxM<64, 16>;
117pub type IdCore64x32 = IdCoreNxM<64, 32>;
118pub type IdCore64x64 = IdCoreNxM<64, 64>;
119pub type IdCore = IdCoreNxM<32, 32>;
120
121pub type StaticId16x0 = StaticIdNxM<16, 0>;
122pub type StaticId16x16 = StaticIdNxM<16, 16>;
123pub type StaticId16x32 = StaticIdNxM<16, 32>;
124pub type StaticId16x64 = StaticIdNxM<16, 64>;
125pub type StaticId32x0 = StaticIdNxM<32, 0>;
126pub type StaticId32x16 = StaticIdNxM<32, 16>;
127pub type StaticId32x32 = StaticIdNxM<32, 32>;
128pub type StaticId32x64 = StaticIdNxM<32, 64>;
129pub type StaticId64x0 = StaticIdNxM<64, 0>;
130pub type StaticId64x16 = StaticIdNxM<64, 16>;
131pub type StaticId64x32 = StaticIdNxM<64, 32>;
132pub type StaticId64x64 = StaticIdNxM<64, 64>;
133pub type StaticId = StaticIdNxM<32, 32>;
134
135static ID_CACHE_16X0: Lazy<Mutex<AHashMap<IdCore16x0, &'static IdCore16x0>>> = Lazy::new(|| Mutex::new(AHashMap::default()));
136static DEFAULT_ID_16X0: Lazy<StaticId16x0> = Lazy::new(|| StaticId16x0::from_str(""));
137
138static ID_CACHE_16X16: Lazy<Mutex<AHashMap<IdCore16x16, &'static IdCore16x16>>> = Lazy::new(|| Mutex::new(AHashMap::default()));
139static DEFAULT_ID_16X16: Lazy<StaticId16x16> = Lazy::new(|| StaticId16x16::from_str("", ""));
140
141static ID_CACHE_16X32: Lazy<Mutex<AHashMap<IdCore16x32, &'static IdCore16x32>>> = Lazy::new(|| Mutex::new(AHashMap::default()));
142static DEFAULT_ID_16X32: Lazy<StaticId16x32> = Lazy::new(|| StaticId16x32::from_str("", ""));
143
144static ID_CACHE_16X64: Lazy<Mutex<AHashMap<IdCore16x64, &'static IdCore16x64>>> = Lazy::new(|| Mutex::new(AHashMap::default()));
145static DEFAULT_ID_16X64: Lazy<StaticId16x64> = Lazy::new(|| StaticId16x64::from_str("", ""));
146
147static ID_CACHE_32X0: Lazy<Mutex<AHashMap<IdCore32x0, &'static IdCore32x0>>> = Lazy::new(|| Mutex::new(AHashMap::default()));
148static DEFAULT_ID_32X0: Lazy<StaticId32x0> = Lazy::new(|| StaticId32x0::from_str(""));
149
150static ID_CACHE_32X16: Lazy<Mutex<AHashMap<IdCore32x16, &'static IdCore32x16>>> = Lazy::new(|| Mutex::new(AHashMap::default()));
151static DEFAULT_ID_32X16: Lazy<StaticId32x16> = Lazy::new(|| StaticId32x16::from_str("", ""));
152
153static ID_CACHE_32X32: Lazy<Mutex<AHashMap<IdCore32x32, &'static IdCore32x32>>> = Lazy::new(|| Mutex::new(AHashMap::default()));
154static DEFAULT_ID_32X32: Lazy<StaticId32x32> = Lazy::new(|| StaticId32x32::from_str("", ""));
155
156static ID_CACHE_32X64: Lazy<Mutex<AHashMap<IdCore32x64, &'static IdCore32x64>>> = Lazy::new(|| Mutex::new(AHashMap::default()));
157static DEFAULT_ID_32X64: Lazy<StaticId32x64> = Lazy::new(|| StaticId32x64::from_str("", ""));
158
159static ID_CACHE_64X0: Lazy<Mutex<AHashMap<IdCore64x0, &'static IdCore64x0>>> = Lazy::new(|| Mutex::new(AHashMap::default()));
160static DEFAULT_ID_64X0: Lazy<StaticId64x0> = Lazy::new(|| StaticId64x0::from_str(""));
161
162static ID_CACHE_64X16: Lazy<Mutex<AHashMap<IdCore64x16, &'static IdCore64x16>>> = Lazy::new(|| Mutex::new(AHashMap::default()));
163static DEFAULT_ID_64X16: Lazy<StaticId64x16> = Lazy::new(|| StaticId64x16::from_str("", ""));
164
165static ID_CACHE_64X32: Lazy<Mutex<AHashMap<IdCore64x32, &'static IdCore64x32>>> = Lazy::new(|| Mutex::new(AHashMap::default()));
166static DEFAULT_ID_64X32: Lazy<StaticId64x32> = Lazy::new(|| StaticId64x32::from_str("", ""));
167
168static ID_CACHE_64X64: Lazy<Mutex<AHashMap<IdCore64x64, &'static IdCore64x64>>> = Lazy::new(|| Mutex::new(AHashMap::default()));
169static DEFAULT_ID_64X64: Lazy<StaticId64x64> = Lazy::new(|| StaticId64x64::from_str("", ""));
170
171impl StaticId16x0 {
172 #[inline]
173 #[must_use]
174 pub fn from_str(code: &str) -> Self {
175 let id = IdCore16x0 {
176 code: Symbol::from(code),
177 venue: Symbol::from(""),
178
179 };
180 let mut cache = ID_CACHE_16X0.lock().unwrap();
181 let interned = *cache.entry(id.clone()).or_insert_with(|| Box::leak(Box::new(id)));
182 StaticId16x0 { id_ptr: interned as *const IdCore16x0 }
183 }
184
185 #[inline]
186 #[must_use]
187 pub fn from_bytes(code: &[u8]) -> Self {
188 let id = IdCore16x0 {
189 code: Symbol::from(code),
190 venue: Symbol::from(""),
191 };
192 let mut cache = ID_CACHE_16X0.lock().unwrap();
193 let interned = *cache.entry(id.clone()).or_insert_with(|| Box::leak(Box::new(id)));
194 StaticId16x0 { id_ptr: interned as *const IdCore16x0 }
195 }
196
197 #[inline]
198 pub fn cache_len() -> usize {
199 ID_CACHE_16X0.lock().unwrap().len()
200 }
201
202 #[inline]
203 pub fn get_id(&self) -> &IdCore16x0 {
204 unsafe { &*self.id_ptr }
205 }
206}
207
208impl Default for StaticId16x0 {
209 fn default() -> Self {
210 *DEFAULT_ID_16X0
211 }
212}
213
214impl StaticId32x0 {
215 #[inline]
216 #[must_use]
217 pub fn from_str(code: &str) -> Self {
218 let id = IdCore32x0 {
219 code: Symbol::from(code),
220 venue: Symbol::from(""),
221 };
222
223 let mut cache = ID_CACHE_32X0.lock().unwrap();
224 let interned = *cache.entry(id.clone()).or_insert_with(|| Box::leak(Box::new(id)));
225 StaticId32x0 { id_ptr: interned as *const IdCore32x0 }
226 }
227
228 #[inline]
229 #[must_use]
230 pub fn from_bytes(code: &[u8]) -> Self {
231 let id = IdCore32x0 {
232 code: Symbol::from(code),
233 venue: Symbol::from(""),
234 };
235 let mut cache = ID_CACHE_32X0.lock().unwrap();
236 let interned = *cache.entry(id.clone()).or_insert_with(|| Box::leak(Box::new(id)));
237 StaticId32x0 { id_ptr: interned as *const IdCore32x0 }
238 }
239
240 #[inline]
241 pub fn cache_len() -> usize {
242 ID_CACHE_32X0.lock().unwrap().len()
243 }
244
245 #[inline]
246 pub fn get_id(&self) -> &IdCore32x0 {
247 unsafe { &*self.id_ptr }
248 }
249}
250
251impl Default for StaticId32x0 {
252 fn default() -> Self {
253 *DEFAULT_ID_32X0
254 }
255}
256
257impl StaticId64x0 {
258 #[inline]
259 #[must_use]
260 pub fn from_str(code: &str) -> Self {
261 let id = IdCore64x0 {
262 code: Symbol::from(code),
263 venue: Symbol::from(""),
264 };
265 let mut cache = ID_CACHE_64X0.lock().unwrap();
266 let interned = *cache.entry(id.clone()).or_insert_with(|| Box::leak(Box::new(id)));
267 StaticId64x0 { id_ptr: interned as *const IdCore64x0 }
268 }
269
270 #[inline]
271 #[must_use]
272 pub fn from_bytes(code: &[u8]) -> Self {
273 let id = IdCore64x0 {
274 code: Symbol::from(code),
275 venue: Symbol::from(""),
276 };
277 let mut cache = ID_CACHE_64X0.lock().unwrap();
278 let interned = *cache.entry(id.clone()).or_insert_with(|| Box::leak(Box::new(id)));
279 StaticId64x0 { id_ptr: interned as *const IdCore64x0 }
280 }
281
282 #[inline]
283 pub fn cache_len() -> usize {
284 ID_CACHE_64X0.lock().unwrap().len()
285 }
286
287 #[inline]
288 pub fn get_id(&self) -> &IdCore64x0 {
289 unsafe { &*self.id_ptr }
290 }
291}
292
293impl Default for StaticId64x0 {
294 fn default() -> Self {
295 *DEFAULT_ID_64X0
296 }
297}
298
299impl StaticId16x16 {
300 #[inline]
301 #[must_use]
302 pub fn from_str(code: &str, venue: &str) -> Self {
303 let id = IdCore16x16 {
304 code: Symbol::from(code),
305 venue: Symbol::from(venue),
306 };
307 let mut cache = ID_CACHE_16X16.lock().unwrap();
308 let interned = *cache.entry(id.clone()).or_insert_with(|| Box::leak(Box::new(id)));
309 StaticId16x16 { id_ptr: interned as *const IdCore16x16 }
310 }
311
312 #[inline]
313 #[must_use]
314 pub fn from_bytes(code: &[u8], venue: &[u8]) -> Self {
315 let id = IdCore16x16 {
316 code: Symbol::from(code),
317 venue: Symbol::from(venue),
318 };
319 let mut cache = ID_CACHE_16X16.lock().unwrap();
320 let interned = *cache.entry(id.clone()).or_insert_with(|| Box::leak(Box::new(id)));
321 StaticId16x16 { id_ptr: interned as *const IdCore16x16 }
322 }
323
324 #[inline]
325 #[must_use]
326 pub fn from_combined_str(combined: &str) -> Self {
327 let (code, venue) = combined.split_at(combined.find('@').unwrap());
328 let venue = &venue[1..];
329 Self::from_str(code, venue)
330 }
331
332 #[inline]
333 pub fn cache_len() -> usize {
334 ID_CACHE_16X16.lock().unwrap().len()
335 }
336
337 #[inline]
338 pub fn get_id(&self) -> &IdCore16x16 {
339 unsafe { &*self.id_ptr }
340 }
341}
342
343impl Default for StaticId16x16 {
344 fn default() -> Self {
345 *DEFAULT_ID_16X16
346 }
347}
348
349impl<'de> Deserialize<'de> for StaticId16x16 {
350 fn deserialize<D>(deserializer: D) -> Result<StaticId16x16, D::Error>
351 where
352 D: Deserializer<'de>,
353 {
354 let s = String::deserialize(deserializer)?;
355 Ok(StaticId16x16::from_combined_str(&s))
356 }
357}
358
359impl StaticId16x32 {
362 #[inline]
363 #[must_use]
364 pub fn from_str(code: &str, venue: &str) -> Self {
365 let id = IdCore16x32 {
366 code: Symbol::from(code),
367 venue: Symbol::from(venue),
368 };
369 let mut cache = ID_CACHE_16X32.lock().unwrap();
370 let interned = *cache.entry(id.clone()).or_insert_with(|| Box::leak(Box::new(id)));
371 StaticId16x32 { id_ptr: interned as *const IdCore16x32 }
372 }
373
374 #[inline]
375 #[must_use]
376 pub fn from_bytes(code: &[u8], venue: &[u8]) -> Self {
377 let id = IdCore16x32 {
378 code: Symbol::from(code),
379 venue: Symbol::from(venue),
380 };
381 let mut cache = ID_CACHE_16X32.lock().unwrap();
382 let interned = *cache.entry(id.clone()).or_insert_with(|| Box::leak(Box::new(id)));
383 StaticId16x32 { id_ptr: interned as *const IdCore16x32 }
384 }
385
386 #[inline]
387 #[must_use]
388 pub fn from_combined_str(combined: &str) -> Self {
389 let (code, venue) = combined.split_at(combined.find('@').unwrap());
390 let venue = &venue[1..];
391 Self::from_str(code, venue)
392 }
393
394 #[inline]
395 pub fn cache_len() -> usize {
396 ID_CACHE_16X32.lock().unwrap().len()
397 }
398
399 #[inline]
400 pub fn get_id(&self) -> &IdCore16x32 {
401 unsafe { &*self.id_ptr }
402 }
403}
404
405impl Default for StaticId16x32 {
406 fn default() -> Self {
407 *DEFAULT_ID_16X32
408 }
409}
410
411impl<'de> Deserialize<'de> for StaticId16x32 {
412 fn deserialize<D>(deserializer: D) -> Result<StaticId16x32, D::Error>
413 where
414 D: Deserializer<'de>,
415 {
416 let s = String::deserialize(deserializer)?;
417 Ok(StaticId16x32::from_combined_str(&s))
418 }
419}
420impl StaticId16x64 {
422 #[inline]
423 #[must_use]
424 pub fn from_str(code: &str, venue: &str) -> Self {
425 let id = IdCore16x64 {
426 code: Symbol::from(code),
427 venue: Symbol::from(venue),
428 };
429 let mut cache = ID_CACHE_16X64.lock().unwrap();
430 let interned = *cache.entry(id.clone()).or_insert_with(|| Box::leak(Box::new(id)));
431 StaticId16x64 { id_ptr: interned as *const IdCore16x64 }
432 }
433
434 #[inline]
435 #[must_use]
436 pub fn from_bytes(code: &[u8], venue: &[u8]) -> Self {
437 let id = IdCore16x64 {
438 code: Symbol::from(code),
439 venue: Symbol::from(venue),
440 };
441 let mut cache = ID_CACHE_16X64.lock().unwrap();
442 let interned = *cache.entry(id.clone()).or_insert_with(|| Box::leak(Box::new(id)));
443 StaticId16x64 { id_ptr: interned as *const IdCore16x64 }
444 }
445
446 #[inline]
447 #[must_use]
448 pub fn from_combined_str(combined: &str) -> Self {
449 let (code, venue) = combined.split_at(combined.find('@').unwrap());
450 let venue = &venue[1..];
451 Self::from_str(code, venue)
452 }
453
454 #[inline]
455 pub fn cache_len() -> usize {
456 ID_CACHE_16X64.lock().unwrap().len()
457 }
458
459 #[inline]
460 pub fn get_id(&self) -> &IdCore16x64 {
461 unsafe { &*self.id_ptr }
462 }
463}
464
465impl Default for StaticId16x64 {
466 fn default() -> Self {
467 *DEFAULT_ID_16X64
468 }
469}
470
471impl<'de> Deserialize<'de> for StaticId16x64 {
472 fn deserialize<D>(deserializer: D) -> Result<StaticId16x64, D::Error>
473 where
474 D: Deserializer<'de>,
475 {
476 let s = String::deserialize(deserializer)?;
477 Ok(StaticId16x64::from_combined_str(&s))
478 }
479}
480
481impl StaticId32x16 {
483 #[inline]
484 #[must_use]
485 pub fn from_str(code: &str, venue: &str) -> Self {
486 let id = IdCore32x16 {
487 code: Symbol::from(code),
488 venue: Symbol::from(venue),
489 };
490 let mut cache = ID_CACHE_32X16.lock().unwrap();
491 let interned = *cache.entry(id.clone()).or_insert_with(|| Box::leak(Box::new(id)));
492 StaticId32x16 { id_ptr: interned as *const IdCore32x16 }
493 }
494
495 #[inline]
496 #[must_use]
497 pub fn from_bytes(code: &[u8], venue: &[u8]) -> Self {
498 let id = IdCore32x16 {
499 code: Symbol::from(code),
500 venue: Symbol::from(venue),
501 };
502 let mut cache = ID_CACHE_32X16.lock().unwrap();
503 let interned = *cache.entry(id.clone()).or_insert_with(|| Box::leak(Box::new(id)));
504 StaticId32x16 { id_ptr: interned as *const IdCore32x16 }
505 }
506
507 #[inline]
508 #[must_use]
509 pub fn from_combined_str(combined: &str) -> Self {
510 let (code, venue) = combined.split_at(combined.find('@').unwrap());
511 let venue = &venue[1..];
512 Self::from_str(code, venue)
513 }
514
515 #[inline]
516 pub fn cache_len() -> usize {
517 ID_CACHE_32X16.lock().unwrap().len()
518 }
519
520 #[inline]
521 pub fn get_id(&self) -> &IdCore32x16 {
522 unsafe { &*self.id_ptr }
523 }
524}
525
526impl Default for StaticId32x16 {
527 fn default() -> Self {
528 *DEFAULT_ID_32X16
529 }
530}
531
532impl<'de> Deserialize<'de> for StaticId32x16 {
533 fn deserialize<D>(deserializer: D) -> Result<StaticId32x16, D::Error>
534 where
535 D: Deserializer<'de>,
536 {
537 let s = String::deserialize(deserializer)?;
538 Ok(StaticId32x16::from_combined_str(&s))
539 }
540}
541
542impl StaticId32x32 {
545 #[inline]
546 #[must_use]
547 pub fn from_str(code: &str, venue: &str) -> Self {
548 let id = IdCore32x32 {
549 code: Symbol::from(code),
550 venue: Symbol::from(venue),
551 };
552 let mut cache = ID_CACHE_32X32.lock().unwrap();
553 let interned = *cache.entry(id.clone()).or_insert_with(|| Box::leak(Box::new(id)));
554 StaticId32x32 { id_ptr: interned as *const IdCore32x32 }
555 }
556
557 #[inline]
558 #[must_use]
559 pub fn from_bytes(code: &[u8], venue: &[u8]) -> Self {
560 let id = IdCore32x32 {
561 code: Symbol::from(code),
562 venue: Symbol::from(venue),
563 };
564 let mut cache = ID_CACHE_32X32.lock().unwrap();
565 let interned = *cache.entry(id.clone()).or_insert_with(|| Box::leak(Box::new(id)));
566 StaticId32x32 { id_ptr: interned as *const IdCore32x32 }
567 }
568
569 #[inline]
570 #[must_use]
571 pub fn from_combined_str(combined: &str) -> Self {
572 let (code, venue) = combined.split_at(combined.find('@').unwrap());
573 let venue = &venue[1..];
574 Self::from_str(code, venue)
575 }
576
577 #[inline]
578 pub fn cache_len() -> usize {
579 ID_CACHE_32X32.lock().unwrap().len()
580 }
581
582 #[inline]
583 pub fn get_id(&self) -> &IdCore32x32 {
584 unsafe { &*self.id_ptr }
585 }
586}
587
588impl Default for StaticId32x32 {
589 fn default() -> Self {
590 *DEFAULT_ID_32X32
591 }
592}
593
594impl<'de> Deserialize<'de> for StaticId32x32 {
595 fn deserialize<D>(deserializer: D) -> Result<StaticId32x32, D::Error>
596 where
597 D: Deserializer<'de>,
598 {
599 let s = String::deserialize(deserializer)?;
600 Ok(StaticId32x32::from_combined_str(&s))
601 }
602}
603
604impl StaticId32x64 {
607 #[inline]
608 #[must_use]
609 pub fn from_str(code: &str, venue: &str) -> Self {
610 let id = IdCore32x64 {
611 code: Symbol::from(code),
612 venue: Symbol::from(venue),
613 };
614 let mut cache = ID_CACHE_32X64.lock().unwrap();
615 let interned = *cache.entry(id.clone()).or_insert_with(|| Box::leak(Box::new(id)));
616 StaticId32x64 { id_ptr: interned as *const IdCore32x64 }
617 }
618
619 #[inline]
620 #[must_use]
621 pub fn from_bytes(code: &[u8], venue: &[u8]) -> Self {
622 let id = IdCore32x64 {
623 code: Symbol::from(code),
624 venue: Symbol::from(venue),
625 };
626 let mut cache = ID_CACHE_32X64.lock().unwrap();
627 let interned = *cache.entry(id.clone()).or_insert_with(|| Box::leak(Box::new(id)));
628 StaticId32x64 { id_ptr: interned as *const IdCore32x64 }
629 }
630
631 #[inline]
632 #[must_use]
633 pub fn from_combined_str(combined: &str) -> Self {
634 let (code, venue) = combined.split_at(combined.find('@').unwrap());
635 let venue = &venue[1..];
636 Self::from_str(code, venue)
637 }
638
639 #[inline]
640 pub fn cache_len() -> usize {
641 ID_CACHE_32X64.lock().unwrap().len()
642 }
643
644 #[inline]
645 pub fn get_id(&self) -> &IdCore32x64 {
646 unsafe { &*self.id_ptr }
647 }
648}
649
650impl Default for StaticId32x64 {
651 fn default() -> Self {
652 *DEFAULT_ID_32X64
653 }
654}
655
656impl<'de> Deserialize<'de> for StaticId32x64 {
657 fn deserialize<D>(deserializer: D) -> Result<StaticId32x64, D::Error>
658 where
659 D: Deserializer<'de>,
660 {
661 let s = String::deserialize(deserializer)?;
662 Ok(StaticId32x64::from_combined_str(&s))
663 }
664}
665
666impl StaticId64x16 {
669 #[inline]
670 #[must_use]
671 pub fn from_str(code: &str, venue: &str) -> Self {
672 let id = IdCore64x16 {
673 code: Symbol::from(code),
674 venue: Symbol::from(venue),
675 };
676 let mut cache = ID_CACHE_64X16.lock().unwrap();
677 let interned = *cache.entry(id.clone()).or_insert_with(|| Box::leak(Box::new(id)));
678 StaticId64x16 { id_ptr: interned as *const IdCore64x16 }
679 }
680
681 #[inline]
682 #[must_use]
683 pub fn from_bytes(code: &[u8], venue: &[u8]) -> Self {
684 let id = IdCore64x16 {
685 code: Symbol::from(code),
686 venue: Symbol::from(venue),
687 };
688 let mut cache = ID_CACHE_64X16.lock().unwrap();
689 let interned = *cache.entry(id.clone()).or_insert_with(|| Box::leak(Box::new(id)));
690 StaticId64x16 { id_ptr: interned as *const IdCore64x16 }
691 }
692
693 #[inline]
694 #[must_use]
695 pub fn from_combined_str(combined: &str) -> Self {
696 let (code, venue) = combined.split_at(combined.find('@').unwrap());
697 let venue = &venue[1..];
698 Self::from_str(code, venue)
699 }
700
701 #[inline]
702 pub fn cache_len() -> usize {
703 ID_CACHE_64X16.lock().unwrap().len()
704 }
705
706 #[inline]
707 pub fn get_id(&self) -> &IdCore64x16 {
708 unsafe { &*self.id_ptr }
709 }
710}
711
712impl Default for StaticId64x16 {
713 fn default() -> Self {
714 *DEFAULT_ID_64X16
715 }
716}
717
718impl<'de> Deserialize<'de> for StaticId64x16 {
719 fn deserialize<D>(deserializer: D) -> Result<StaticId64x16, D::Error>
720 where
721 D: Deserializer<'de>,
722 {
723 let s = String::deserialize(deserializer)?;
724 Ok(StaticId64x16::from_combined_str(&s))
725 }
726}
727
728impl StaticId64x32 {
731 #[inline]
732 #[must_use]
733 pub fn from_str(code: &str, venue: &str) -> Self {
734 let id = IdCore64x32 {
735 code: Symbol::from(code),
736 venue: Symbol::from(venue),
737 };
738 let mut cache = ID_CACHE_64X32.lock().unwrap();
739 let interned = *cache.entry(id.clone()).or_insert_with(|| Box::leak(Box::new(id)));
740 StaticId64x32 { id_ptr: interned as *const IdCore64x32 }
741 }
742
743 #[inline]
744 #[must_use]
745 pub fn from_bytes(code: &[u8], venue: &[u8]) -> Self {
746 let id = IdCore64x32 {
747 code: Symbol::from(code),
748 venue: Symbol::from(venue),
749 };
750 let mut cache = ID_CACHE_64X32.lock().unwrap();
751 let interned = *cache.entry(id.clone()).or_insert_with(|| Box::leak(Box::new(id)));
752 StaticId64x32 { id_ptr: interned as *const IdCore64x32 }
753 }
754
755 #[inline]
756 #[must_use]
757 pub fn from_combined_str(combined: &str) -> Self {
758 let (code, venue) = combined.split_at(combined.find('@').unwrap());
759 let venue = &venue[1..];
760 Self::from_str(code, venue)
761 }
762
763 #[inline]
764 pub fn cache_len() -> usize {
765 ID_CACHE_64X32.lock().unwrap().len()
766 }
767
768 #[inline]
769 pub fn get_id(&self) -> &IdCore64x32 {
770 unsafe { &*self.id_ptr }
771 }
772}
773
774impl Default for StaticId64x32 {
775 fn default() -> Self {
776 *DEFAULT_ID_64X32
777 }
778}
779
780impl<'de> Deserialize<'de> for StaticId64x32 {
781 fn deserialize<D>(deserializer: D) -> Result<StaticId64x32, D::Error>
782 where
783 D: Deserializer<'de>,
784 {
785 let s = String::deserialize(deserializer)?;
786 Ok(StaticId64x32::from_combined_str(&s))
787 }
788}
789
790impl StaticId64x64 {
793 #[inline]
794 #[must_use]
795 pub fn from_str(code: &str, venue: &str) -> Self {
796 let id = IdCore64x64 {
797 code: Symbol::from(code),
798 venue: Symbol::from(venue),
799 };
800 let mut cache = ID_CACHE_64X64.lock().unwrap();
801 let interned = *cache.entry(id.clone()).or_insert_with(|| Box::leak(Box::new(id)));
802 StaticId64x64 { id_ptr: interned as *const IdCore64x64 }
803 }
804
805 #[inline]
806 #[must_use]
807 pub fn from_bytes(code: &[u8], venue: &[u8]) -> Self {
808 let id = IdCore64x64 {
809 code: Symbol::from(code),
810 venue: Symbol::from(venue),
811 };
812 let mut cache = ID_CACHE_64X64.lock().unwrap();
813 let interned = *cache.entry(id.clone()).or_insert_with(|| Box::leak(Box::new(id)));
814 StaticId64x64 { id_ptr: interned as *const IdCore64x64 }
815 }
816
817 #[inline]
818 #[must_use]
819 pub fn from_combined_str(combined: &str) -> Self {
820 let (code, venue) = combined.split_at(combined.find('@').unwrap());
821 let venue = &venue[1..];
822 Self::from_str(code, venue)
823 }
824
825 #[inline]
826 pub fn cache_len() -> usize {
827 ID_CACHE_64X64.lock().unwrap().len()
828 }
829
830 #[inline]
831 pub fn get_id(&self) -> &IdCore64x64 {
832 unsafe { &*self.id_ptr }
833 }
834}
835
836impl Default for StaticId64x64 {
837 fn default() -> Self {
838 *DEFAULT_ID_64X64
839 }
840}
841
842impl<'de> Deserialize<'de> for StaticId64x64 {
843 fn deserialize<D>(deserializer: D) -> Result<StaticId64x64, D::Error>
844 where
845 D: Deserializer<'de>,
846 {
847 let s = String::deserialize(deserializer)?;
848 Ok(StaticId64x64::from_combined_str(&s))
849 }
850}