Skip to main content

syster/base/
file_id.rs

1//! File identifiers for tracking source files.
2
3use std::fmt;
4
5/// An interned identifier for a source file.
6///
7/// `FileId` is a lightweight handle (just a u32) that uniquely identifies
8/// a file within the workspace. The actual path is stored elsewhere.
9///
10/// Using `FileId` instead of `PathBuf` throughout the codebase:
11/// - Makes comparisons O(1) instead of O(n)
12/// - Reduces memory usage (4 bytes vs ~24+ bytes)
13/// - Enables cheap copying and hashing
14#[derive(Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
15pub struct FileId(pub u32);
16
17impl FileId {
18    /// Create a new FileId from a raw index.
19    #[inline]
20    pub const fn new(id: u32) -> Self {
21        Self(id)
22    }
23
24    /// Get the raw index.
25    #[inline]
26    pub const fn index(self) -> u32 {
27        self.0
28    }
29}
30
31impl fmt::Debug for FileId {
32    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33        write!(f, "FileId({})", self.0)
34    }
35}
36
37impl fmt::Display for FileId {
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        write!(f, "file#{}", self.0)
40    }
41}
42
43impl From<u32> for FileId {
44    #[inline]
45    fn from(id: u32) -> Self {
46        Self(id)
47    }
48}
49
50impl From<FileId> for u32 {
51    #[inline]
52    fn from(id: FileId) -> Self {
53        id.0
54    }
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60
61    #[test]
62    fn test_file_id_equality() {
63        let a = FileId::new(1);
64        let b = FileId::new(1);
65        let c = FileId::new(2);
66
67        assert_eq!(a, b);
68        assert_ne!(a, c);
69    }
70
71    #[test]
72    fn test_file_id_hash() {
73        use std::collections::HashSet;
74
75        let mut set = HashSet::new();
76        set.insert(FileId::new(1));
77        set.insert(FileId::new(2));
78        set.insert(FileId::new(1)); // duplicate
79
80        assert_eq!(set.len(), 2);
81    }
82
83    #[test]
84    fn test_file_id_size() {
85        assert_eq!(std::mem::size_of::<FileId>(), 4);
86    }
87}