1use std::{fmt, sync::LazyLock};
2
3use crate::{Id, Interner};
4
5static INTERNER: LazyLock<Interner> = LazyLock::new(Interner::default);
6
7#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
8pub(crate) struct FilePath(Id);
9
10impl fmt::Debug for FilePath {
11 #[inline]
12 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13 let s = INTERNER.lookup(self.0);
14 fmt::Debug::fmt(s, f)
15 }
16}
17
18impl fmt::Display for FilePath {
19 #[inline]
20 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21 let s = INTERNER.lookup(self.0);
22 fmt::Display::fmt(s, f)
23 }
24}
25
26impl From<&'static str> for FilePath {
27 #[inline]
28 fn from(s: &'static str) -> Self {
29 let id = INTERNER.intern_static(s);
30 FilePath(id)
31 }
32}
33
34impl From<FilePath> for &'static str {
35 #[inline]
36 fn from(FilePath(id): FilePath) -> Self {
37 INTERNER.lookup(id)
38 }
39}
40
41#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
42#[cfg(feature = "serde")]
43impl serde::Serialize for FilePath {
44 #[inline]
45 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
46 where
47 S: serde::Serializer,
48 {
49 let s = INTERNER.lookup(self.0);
50 serializer.serialize_str(s)
51 }
52}
53
54#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
55#[cfg(feature = "serde")]
56impl<'de> serde::Deserialize<'de> for FilePath {
57 #[inline]
58 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
59 where
60 D: serde::Deserializer<'de>,
61 {
62 let s: &str = serde::Deserialize::deserialize(deserializer)?;
63 let id = INTERNER.intern_normal(s);
64 Ok(FilePath(id))
65 }
66}