file_system/fundamentals/identifiers/file.rs
1//! File identifier types for opened files.
2//!
3//! This module provides file identifier types used to identify opened files
4//! within a task's file descriptor table, similar to file descriptors in
5//! Unix-like systems.
6
7/// File identifier inner type.
8///
9/// This is the underlying numeric type used for file identifiers. The size
10/// is architecture-dependent to optimize memory usage while providing sufficient
11/// identifier space:
12/// - 16 bits (0-65,535) on 32-bit systems
13/// - 32 bits (0-4,294,967,295) on 64-bit systems
14///
15/// This provides a good balance between memory efficiency and identifier space.
16#[cfg(target_pointer_width = "32")]
17pub type FileIdentifierInner = u16;
18#[cfg(target_pointer_width = "64")]
19pub type FileIdentifierInner = u32;
20
21/// Type-safe wrapper for file identifiers.
22///
23/// File identifiers are used to reference opened files within a task's context,
24/// similar to file descriptors in Unix-like systems. Each task maintains its own
25/// file identifier space, allowing for task isolation and security.
26///
27/// # Standard File Identifiers
28///
29/// The following standard identifiers are predefined:
30/// - [`FileIdentifier::STANDARD_IN`] (0) - Standard input
31/// - [`FileIdentifier::STANDARD_OUT`] (1) - Standard output
32/// - [`FileIdentifier::STANDARD_ERROR`] (2) - Standard error
33/// - [`FileIdentifier::MINIMUM`] (3) - First available identifier for regular files
34///
35/// # Examples
36///
37/// ```rust
38/// use file_system::File_identifier_type;
39///
40/// // Standard file identifiers
41/// assert_eq!(File_identifier_type::Standard_in.Into_inner(), 0);
42/// assert_eq!(File_identifier_type::Standard_out.Into_inner(), 1);
43/// assert_eq!(File_identifier_type::Standard_error.Into_inner(), 2);
44///
45/// // Create a custom file identifier
46/// let file_id = File_identifier_type::new(42);
47/// assert_eq!(file_id.Into_inner(), 42);
48/// ```
49#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
50#[repr(transparent)]
51pub struct FileIdentifier(FileIdentifierInner);
52
53impl FileIdentifier {
54 /// Size in bits of the underlying identifier type.
55 pub const SIZE_BITS: u8 = core::mem::size_of::<FileIdentifierInner>() as u8 * 8;
56
57 /// Standard input file identifier (traditionally 0).
58 pub const STANDARD_IN: FileIdentifier = FileIdentifier::new(0);
59
60 /// Standard output file identifier (traditionally 1).
61 pub const STANDARD_OUT: FileIdentifier = FileIdentifier::new(1);
62
63 /// Standard error file identifier (traditionally 2).
64 pub const STANDARD_ERROR: FileIdentifier = FileIdentifier::new(2);
65
66 /// Minimum file identifier available for regular files.
67 ///
68 /// Regular files should use identifiers starting from this value to avoid
69 /// conflicts with standard file identifiers.
70 pub const MINIMUM: FileIdentifier = FileIdentifier::new(3);
71
72 /// Maximum possible file identifier value.
73 pub const MAXIMUM: FileIdentifier = FileIdentifier::new(FileIdentifierInner::MAX);
74
75 /// Create a new file identifier from a raw value.
76 ///
77 /// # Arguments
78 ///
79 /// * `Identifier` - The raw identifier value
80 ///
81 /// # Examples
82 ///
83 /// ```rust
84 /// use file_system::File_identifier_type;
85 ///
86 /// let file_id = File_identifier_type::new(5);
87 /// assert_eq!(file_id.Into_inner(), 5);
88 /// ```
89 pub const fn new(identifier: FileIdentifierInner) -> Self {
90 Self(identifier)
91 }
92
93 /// Get the raw identifier value.
94 ///
95 /// # Returns
96 ///
97 /// The underlying raw identifier value.
98 ///
99 /// # Examples
100 ///
101 /// ```rust
102 /// use file_system::File_identifier_type;
103 ///
104 /// let file_id = File_identifier_type::new(42);
105 /// assert_eq!(file_id.Into_inner(), 42);
106 /// ```
107 pub const fn into_inner(self) -> FileIdentifierInner {
108 self.0
109 }
110}
111
112impl From<FileIdentifierInner> for FileIdentifier {
113 fn from(internal_file_identifier: FileIdentifierInner) -> Self {
114 FileIdentifier(internal_file_identifier)
115 }
116}
117
118impl From<FileIdentifier> for FileIdentifierInner {
119 fn from(internal_file_identifier: FileIdentifier) -> Self {
120 internal_file_identifier.0
121 }
122}
123
124#[cfg(test)]
125mod tests {
126 use super::*;
127
128 #[test]
129 fn test_file_identifier() {
130 let identifier = FileIdentifier::from(0x1234);
131 assert_eq!(identifier, FileIdentifier::new(0x1234));
132 assert_eq!(FileIdentifierInner::from(identifier), 0x1234);
133 }
134}