use crate::Db;
use crate::files::{File, system_path_to_file, vendored_path_to_file};
use crate::system::{SystemPath, SystemPathBuf, SystemVirtualPath, SystemVirtualPathBuf};
use crate::vendored::{VendoredPath, VendoredPathBuf};
use std::fmt::{Display, Formatter};
#[derive(Clone, Debug, Eq, PartialEq, Hash, get_size2::GetSize)]
pub enum FilePath {
System(Box<SystemPath>),
SystemVirtual(Box<SystemVirtualPath>),
Vendored(Box<VendoredPath>),
}
impl FilePath {
#[must_use]
pub fn system(path: impl AsRef<SystemPath>) -> Self {
FilePath::from(path.as_ref())
}
#[must_use]
#[inline]
pub fn as_system_path(&self) -> Option<&SystemPath> {
match self {
FilePath::System(path) => Some(path),
FilePath::Vendored(_) | FilePath::SystemVirtual(_) => None,
}
}
#[must_use]
#[inline]
pub const fn is_system_path(&self) -> bool {
matches!(self, FilePath::System(_))
}
#[must_use]
#[inline]
pub const fn is_system_virtual_path(&self) -> bool {
matches!(self, FilePath::SystemVirtual(_))
}
#[must_use]
#[inline]
pub const fn is_vendored_path(&self) -> bool {
matches!(self, FilePath::Vendored(_))
}
#[must_use]
#[inline]
pub fn as_vendored_path(&self) -> Option<&VendoredPath> {
match self {
FilePath::Vendored(path) => Some(path),
FilePath::System(_) | FilePath::SystemVirtual(_) => None,
}
}
pub fn as_str(&self) -> &str {
match self {
FilePath::System(path) => path.as_str(),
FilePath::Vendored(path) => path.as_str(),
FilePath::SystemVirtual(path) => path.as_str(),
}
}
#[inline]
pub fn to_file(&self, db: &dyn Db) -> Option<File> {
match self {
FilePath::System(path) => system_path_to_file(db, path).ok(),
FilePath::Vendored(path) => vendored_path_to_file(db, path).ok(),
FilePath::SystemVirtual(_) => None,
}
}
#[must_use]
pub fn extension(&self) -> Option<&str> {
match self {
FilePath::System(path) => path.extension(),
FilePath::Vendored(path) => path.extension(),
FilePath::SystemVirtual(_) => None,
}
}
}
impl AsRef<str> for FilePath {
fn as_ref(&self) -> &str {
self.as_str()
}
}
impl From<SystemPathBuf> for FilePath {
fn from(value: SystemPathBuf) -> Self {
Self::System(Box::from(value))
}
}
impl From<&SystemPath> for FilePath {
fn from(value: &SystemPath) -> Self {
Self::System(Box::from(value))
}
}
impl From<VendoredPathBuf> for FilePath {
fn from(value: VendoredPathBuf) -> Self {
Self::Vendored(Box::from(value))
}
}
impl From<&VendoredPath> for FilePath {
fn from(value: &VendoredPath) -> Self {
Self::Vendored(Box::from(value))
}
}
impl From<&SystemVirtualPath> for FilePath {
fn from(value: &SystemVirtualPath) -> Self {
Self::SystemVirtual(Box::from(value))
}
}
impl From<SystemVirtualPathBuf> for FilePath {
fn from(value: SystemVirtualPathBuf) -> Self {
Self::SystemVirtual(Box::from(value))
}
}
impl PartialEq<SystemPath> for FilePath {
#[inline]
fn eq(&self, other: &SystemPath) -> bool {
self.as_system_path()
.is_some_and(|self_path| self_path == other)
}
}
impl PartialEq<FilePath> for SystemPath {
#[inline]
fn eq(&self, other: &FilePath) -> bool {
other == self
}
}
impl PartialEq<SystemPathBuf> for FilePath {
#[inline]
fn eq(&self, other: &SystemPathBuf) -> bool {
self == other.as_path()
}
}
impl PartialEq<FilePath> for SystemPathBuf {
fn eq(&self, other: &FilePath) -> bool {
other == self
}
}
impl PartialEq<VendoredPath> for FilePath {
#[inline]
fn eq(&self, other: &VendoredPath) -> bool {
self.as_vendored_path()
.is_some_and(|self_path| self_path == other)
}
}
impl PartialEq<FilePath> for VendoredPath {
#[inline]
fn eq(&self, other: &FilePath) -> bool {
other == self
}
}
impl PartialEq<VendoredPathBuf> for FilePath {
#[inline]
fn eq(&self, other: &VendoredPathBuf) -> bool {
other.as_path() == self
}
}
impl PartialEq<FilePath> for VendoredPathBuf {
#[inline]
fn eq(&self, other: &FilePath) -> bool {
other == self
}
}
impl Display for FilePath {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
FilePath::System(path) => std::fmt::Display::fmt(path, f),
FilePath::SystemVirtual(path) => std::fmt::Display::fmt(path, f),
FilePath::Vendored(path) => std::fmt::Display::fmt(path, f),
}
}
}