ruff/crates/ruff_db/src/vendored/path.rs

223 lines
4.9 KiB
Rust

use std::borrow::Borrow;
use std::fmt::Formatter;
use std::ops::Deref;
use std::path;
use camino::{Utf8Components, Utf8Path, Utf8PathBuf};
#[repr(transparent)]
#[derive(Debug, Eq, PartialEq, Hash)]
pub struct VendoredPath(Utf8Path);
impl VendoredPath {
pub fn new(path: &(impl AsRef<Utf8Path> + ?Sized)) -> &Self {
let path = path.as_ref();
// SAFETY: VendoredPath is marked as #[repr(transparent)] so the conversion from a
// *const Utf8Path to a *const VendoredPath is valid.
unsafe { &*(path as *const Utf8Path as *const VendoredPath) }
}
pub fn file_name(&self) -> Option<&str> {
self.0.file_name()
}
pub fn to_path_buf(&self) -> VendoredPathBuf {
VendoredPathBuf(self.0.to_path_buf())
}
pub fn as_str(&self) -> &str {
self.0.as_str()
}
pub fn as_utf8_path(&self) -> &camino::Utf8Path {
&self.0
}
pub fn as_std_path(&self) -> &path::Path {
self.0.as_std_path()
}
pub fn components(&self) -> Utf8Components<'_> {
self.0.components()
}
#[must_use]
pub fn extension(&self) -> Option<&str> {
self.0.extension()
}
#[must_use]
pub fn with_pyi_extension(&self) -> VendoredPathBuf {
VendoredPathBuf(self.0.with_extension("pyi"))
}
#[must_use]
pub fn join(&self, other: impl AsRef<VendoredPath>) -> VendoredPathBuf {
VendoredPathBuf(self.0.join(other.as_ref()))
}
#[must_use]
pub fn ends_with(&self, suffix: impl AsRef<VendoredPath>) -> bool {
self.0.ends_with(suffix.as_ref())
}
#[must_use]
pub fn parent(&self) -> Option<&Self> {
self.0.parent().map(Self::new)
}
#[must_use]
pub fn file_stem(&self) -> Option<&str> {
self.0.file_stem()
}
pub fn strip_prefix(
&self,
prefix: impl AsRef<VendoredPath>,
) -> Result<&Self, path::StripPrefixError> {
self.0.strip_prefix(prefix.as_ref()).map(Self::new)
}
}
impl ToOwned for VendoredPath {
type Owned = VendoredPathBuf;
fn to_owned(&self) -> VendoredPathBuf {
self.to_path_buf()
}
}
#[repr(transparent)]
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
pub struct VendoredPathBuf(Utf8PathBuf);
impl get_size2::GetSize for VendoredPathBuf {
fn get_heap_size(&self) -> usize {
self.0.capacity()
}
}
impl Default for VendoredPathBuf {
fn default() -> Self {
Self::new()
}
}
impl VendoredPathBuf {
pub fn new() -> Self {
Self(Utf8PathBuf::new())
}
#[inline]
pub fn as_path(&self) -> &VendoredPath {
VendoredPath::new(&self.0)
}
pub fn push(&mut self, component: impl AsRef<VendoredPath>) {
self.0.push(component.as_ref())
}
}
impl Borrow<VendoredPath> for VendoredPathBuf {
fn borrow(&self) -> &VendoredPath {
self.as_path()
}
}
impl AsRef<VendoredPath> for VendoredPathBuf {
fn as_ref(&self) -> &VendoredPath {
self.as_path()
}
}
impl AsRef<VendoredPath> for VendoredPath {
#[inline]
fn as_ref(&self) -> &VendoredPath {
self
}
}
impl AsRef<VendoredPath> for Utf8Path {
#[inline]
fn as_ref(&self) -> &VendoredPath {
VendoredPath::new(self)
}
}
impl AsRef<VendoredPath> for Utf8PathBuf {
#[inline]
fn as_ref(&self) -> &VendoredPath {
VendoredPath::new(self.as_path())
}
}
impl AsRef<VendoredPath> for str {
#[inline]
fn as_ref(&self) -> &VendoredPath {
VendoredPath::new(self)
}
}
impl AsRef<VendoredPath> for String {
#[inline]
fn as_ref(&self) -> &VendoredPath {
VendoredPath::new(self)
}
}
impl AsRef<path::Path> for VendoredPath {
#[inline]
fn as_ref(&self) -> &path::Path {
self.0.as_std_path()
}
}
impl AsRef<Utf8Path> for VendoredPath {
#[inline]
fn as_ref(&self) -> &Utf8Path {
&self.0
}
}
impl Deref for VendoredPathBuf {
type Target = VendoredPath;
fn deref(&self) -> &Self::Target {
self.as_path()
}
}
impl From<&str> for VendoredPathBuf {
fn from(value: &str) -> Self {
Self(Utf8PathBuf::from(value))
}
}
impl<'a> TryFrom<&'a path::Path> for &'a VendoredPath {
type Error = camino::FromPathError;
fn try_from(value: &'a path::Path) -> Result<Self, Self::Error> {
Ok(VendoredPath::new(<&camino::Utf8Path>::try_from(value)?))
}
}
impl TryFrom<path::PathBuf> for VendoredPathBuf {
type Error = camino::FromPathBufError;
fn try_from(value: path::PathBuf) -> Result<Self, Self::Error> {
Ok(VendoredPathBuf(camino::Utf8PathBuf::try_from(value)?))
}
}
impl std::fmt::Display for VendoredPath {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "vendored://{}", &self.0)
}
}
impl std::fmt::Display for VendoredPathBuf {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.as_path(), f)
}
}