1use crate::Db;
2use crate::files::{File, system_path_to_file, vendored_path_to_file};
3use crate::system::{SystemPath, SystemPathBuf, SystemVirtualPath, SystemVirtualPathBuf};
4use crate::vendored::{VendoredPath, VendoredPathBuf};
5use std::fmt::{Display, Formatter};
6
7#[derive(Clone, Debug, Eq, PartialEq, Hash, get_size2::GetSize)]
15pub enum FilePath {
16 System(Box<SystemPath>),
18 SystemVirtual(Box<SystemVirtualPath>),
20 Vendored(Box<VendoredPath>),
22}
23
24impl FilePath {
25 #[must_use]
27 pub fn system(path: impl AsRef<SystemPath>) -> Self {
28 FilePath::from(path.as_ref())
29 }
30
31 #[must_use]
32 #[inline]
33 pub fn as_system_path(&self) -> Option<&SystemPath> {
34 match self {
35 FilePath::System(path) => Some(path),
36 FilePath::Vendored(_) | FilePath::SystemVirtual(_) => None,
37 }
38 }
39
40 #[must_use]
42 #[inline]
43 pub const fn is_system_path(&self) -> bool {
44 matches!(self, FilePath::System(_))
45 }
46
47 #[must_use]
50 #[inline]
51 pub const fn is_system_virtual_path(&self) -> bool {
52 matches!(self, FilePath::SystemVirtual(_))
53 }
54
55 #[must_use]
57 #[inline]
58 pub const fn is_vendored_path(&self) -> bool {
59 matches!(self, FilePath::Vendored(_))
60 }
61
62 #[must_use]
63 #[inline]
64 pub fn as_vendored_path(&self) -> Option<&VendoredPath> {
65 match self {
66 FilePath::Vendored(path) => Some(path),
67 FilePath::System(_) | FilePath::SystemVirtual(_) => None,
68 }
69 }
70
71 pub fn as_str(&self) -> &str {
73 match self {
74 FilePath::System(path) => path.as_str(),
75 FilePath::Vendored(path) => path.as_str(),
76 FilePath::SystemVirtual(path) => path.as_str(),
77 }
78 }
79
80 #[inline]
87 pub fn to_file(&self, db: &dyn Db) -> Option<File> {
88 match self {
89 FilePath::System(path) => system_path_to_file(db, path).ok(),
90 FilePath::Vendored(path) => vendored_path_to_file(db, path).ok(),
91 FilePath::SystemVirtual(_) => None,
92 }
93 }
94
95 #[must_use]
96 pub fn extension(&self) -> Option<&str> {
97 match self {
98 FilePath::System(path) => path.extension(),
99 FilePath::Vendored(path) => path.extension(),
100 FilePath::SystemVirtual(_) => None,
101 }
102 }
103}
104
105impl AsRef<str> for FilePath {
106 fn as_ref(&self) -> &str {
107 self.as_str()
108 }
109}
110
111impl From<SystemPathBuf> for FilePath {
112 fn from(value: SystemPathBuf) -> Self {
113 Self::System(Box::from(value))
114 }
115}
116
117impl From<&SystemPath> for FilePath {
118 fn from(value: &SystemPath) -> Self {
119 Self::System(Box::from(value))
120 }
121}
122
123impl From<VendoredPathBuf> for FilePath {
124 fn from(value: VendoredPathBuf) -> Self {
125 Self::Vendored(Box::from(value))
126 }
127}
128
129impl From<&VendoredPath> for FilePath {
130 fn from(value: &VendoredPath) -> Self {
131 Self::Vendored(Box::from(value))
132 }
133}
134
135impl From<&SystemVirtualPath> for FilePath {
136 fn from(value: &SystemVirtualPath) -> Self {
137 Self::SystemVirtual(Box::from(value))
138 }
139}
140
141impl From<SystemVirtualPathBuf> for FilePath {
142 fn from(value: SystemVirtualPathBuf) -> Self {
143 Self::SystemVirtual(Box::from(value))
144 }
145}
146
147impl PartialEq<SystemPath> for FilePath {
148 #[inline]
149 fn eq(&self, other: &SystemPath) -> bool {
150 self.as_system_path()
151 .is_some_and(|self_path| self_path == other)
152 }
153}
154
155impl PartialEq<FilePath> for SystemPath {
156 #[inline]
157 fn eq(&self, other: &FilePath) -> bool {
158 other == self
159 }
160}
161
162impl PartialEq<SystemPathBuf> for FilePath {
163 #[inline]
164 fn eq(&self, other: &SystemPathBuf) -> bool {
165 self == other.as_path()
166 }
167}
168
169impl PartialEq<FilePath> for SystemPathBuf {
170 fn eq(&self, other: &FilePath) -> bool {
171 other == self
172 }
173}
174
175impl PartialEq<VendoredPath> for FilePath {
176 #[inline]
177 fn eq(&self, other: &VendoredPath) -> bool {
178 self.as_vendored_path()
179 .is_some_and(|self_path| self_path == other)
180 }
181}
182
183impl PartialEq<FilePath> for VendoredPath {
184 #[inline]
185 fn eq(&self, other: &FilePath) -> bool {
186 other == self
187 }
188}
189
190impl PartialEq<VendoredPathBuf> for FilePath {
191 #[inline]
192 fn eq(&self, other: &VendoredPathBuf) -> bool {
193 other.as_path() == self
194 }
195}
196
197impl PartialEq<FilePath> for VendoredPathBuf {
198 #[inline]
199 fn eq(&self, other: &FilePath) -> bool {
200 other == self
201 }
202}
203
204impl Display for FilePath {
205 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
206 match self {
207 FilePath::System(path) => std::fmt::Display::fmt(path, f),
208 FilePath::SystemVirtual(path) => std::fmt::Display::fmt(path, f),
209 FilePath::Vendored(path) => std::fmt::Display::fmt(path, f),
210 }
211 }
212}