Files
riscv64-kernel/crates/bffs/src/path.rs

152 lines
3.2 KiB
Rust

#[cfg(feature = "alloc")]
use core::{borrow::Borrow, ops::Deref};
#[cfg(feature = "alloc")]
use alloc::borrow::ToOwned;
#[cfg(feature = "alloc")]
use alloc::string::String;
#[repr(transparent)]
#[derive(Debug)]
pub struct Path {
inner: str,
}
impl From<&str> for &Path {
fn from(value: &str) -> Self {
unsafe { &*(value as *const str as *const Path) }
}
}
impl AsRef<Path> for str {
fn as_ref(&self) -> &Path {
unsafe { &*(self as *const str as *const Path) }
}
}
#[cfg(feature = "alloc")]
impl AsRef<Path> for String {
fn as_ref(&self) -> &Path {
self.as_str().as_ref()
}
}
impl AsRef<Path> for Path {
fn as_ref(&self) -> &Path {
self
}
}
impl AsRef<str> for Path {
fn as_ref(&self) -> &str {
self.as_str()
}
}
impl Path {
pub fn new(path: &str) -> &Self {
path.as_ref()
}
pub fn split_path(&self) -> (&str, Option<&Path>) {
if let Some((start, end)) = self.inner.split_once("/") {
if end.is_empty() {
(start, None)
} else {
(start, Some(end.into()))
}
} else {
(&self.inner, None)
}
}
pub fn as_str(&self) -> &str {
&self.inner
}
pub fn is_absolute(&self) -> bool {
self.inner.starts_with("/")
}
pub fn is_relative(&self) -> bool {
!self.is_absolute()
}
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
pub fn is_root(&self) -> bool {
self.as_str() == "/"
}
pub fn starts_with<P: AsRef<Self>>(&self, other: P) -> bool {
let this = self.split_path();
let other = other.as_ref().split_path();
if this.0 == other.0 {
if let Some(this) = this.1
&& let Some(other) = other.1
{
this.starts_with(other)
} else {
other.1.is_none()
}
} else {
false
}
}
pub fn without<P: AsRef<Self>>(&self, other: P) -> &Path {
let this = self.split_path();
let other = other.as_ref().split_path();
if this.0 == other.0 {
match (this.1, other.1) {
(None, None) => Path::new(""),
(None, Some(_)) => todo!(),
(Some(p), None) => p,
(Some(this), Some(other)) => this.without(other),
}
} else {
todo!()
}
}
}
#[cfg(feature = "alloc")]
#[derive(Debug, Hash, PartialEq, Eq)]
pub struct PathBuf {
inner: String,
}
#[cfg(feature = "alloc")]
impl Deref for PathBuf {
type Target = Path;
fn deref(&self) -> &Self::Target {
self.inner.as_str().into()
}
}
#[cfg(feature = "alloc")]
impl AsRef<Path> for PathBuf {
fn as_ref(&self) -> &Path {
self.inner.as_ref()
}
}
#[cfg(feature = "alloc")]
impl Borrow<str> for PathBuf {
fn borrow(&self) -> &str {
&self.inner
}
}
#[cfg(feature = "alloc")]
impl From<&str> for PathBuf {
fn from(val: &str) -> Self {
PathBuf {
inner: val.to_owned(),
}
}
}
#[cfg(feature = "alloc")]
impl From<String> for PathBuf {
fn from(val: String) -> Self {
PathBuf { inner: val }
}
}