lang_util/
file_id.rs

1//! File identifier definition
2
3/// Unique file identifier
4#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
5#[cfg_attr(feature = "serde", derive(rserde::Serialize, rserde::Deserialize))]
6#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
7pub struct FileId(u32);
8
9const MAX_VALUE: u32 = 0x7FFFFFFF;
10const BUILTIN_BIT: u32 = 0x80000000;
11
12impl FileId {
13    /// Create a new file identifier
14    ///
15    /// # Panics
16    ///
17    /// panics if raw is greater than 0x7FFFFFFF
18    pub fn new(raw: u32) -> Self {
19        if raw > MAX_VALUE {
20            panic!("file identifier is too large");
21        }
22
23        Self(raw)
24    }
25
26    /// Create a new file identifier for a built-in string
27    ///
28    /// # Panics
29    ///
30    /// panics if raw is greater than 0x7FFFFFFE
31    pub fn builtin(raw: u32) -> Self {
32        if raw > (MAX_VALUE - 1) {
33            panic!("file identifier is too large");
34        }
35
36        Self(BUILTIN_BIT | (raw + 1))
37    }
38
39    /// Get the number behind this id, regardless of its type
40    pub fn number(&self) -> u32 {
41        if (self.0 & BUILTIN_BIT) == BUILTIN_BIT {
42            let raw = self.0 & !BUILTIN_BIT;
43            if raw == 0 {
44                raw
45            } else {
46                raw - 1
47            }
48        } else {
49            self.0
50        }
51    }
52}
53
54impl Default for FileId {
55    fn default() -> Self {
56        Self(BUILTIN_BIT)
57    }
58}
59
60impl std::fmt::Display for FileId {
61    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62        if (self.0 & BUILTIN_BIT) == BUILTIN_BIT {
63            let raw = self.0 & !BUILTIN_BIT;
64
65            if raw == 0 {
66                write!(f, "internal")
67            } else {
68                write!(f, "builtin-{}", raw - 1)
69            }
70        } else {
71            write!(f, "{}", self.0)
72        }
73    }
74}
75
76impl From<u32> for FileId {
77    fn from(value: u32) -> Self {
78        Self(value)
79    }
80}
81
82impl From<FileId> for u32 {
83    fn from(value: FileId) -> Self {
84        value.0
85    }
86}