use alloc::fmt;
use core::hash::Hash;
use core::ops::{Deref, DerefMut};
use std::ffi::{OsStr, OsString};
use std::path::{Path, PathBuf};
use crate::bytes::HipByt;
use crate::os_string::HipOsStr;
use crate::string::HipStr;
use crate::Backend;
mod cmp;
mod convert;
#[cfg(feature = "serde")]
pub mod serde;
#[cfg(test)]
mod tests;
#[repr(transparent)]
#[allow(clippy::module_name_repetitions)]
pub struct HipPath<'borrow, B>(HipOsStr<'borrow, B>)
where
B: Backend;
impl<'borrow, B> HipPath<'borrow, B>
where
B: Backend,
{
#[inline]
#[must_use]
pub const fn new() -> Self {
Self(HipOsStr::new())
}
#[must_use]
#[inline]
pub fn borrowed<P: AsRef<Path> + ?Sized>(value: &'borrow P) -> Self {
Self(HipOsStr::borrowed(value.as_ref().as_os_str()))
}
#[inline]
#[must_use]
pub const fn is_inline(&self) -> bool {
self.0.is_inline()
}
#[inline]
#[must_use]
pub const fn is_borrowed(&self) -> bool {
self.0.is_borrowed()
}
#[inline]
#[must_use]
pub const fn is_allocated(&self) -> bool {
self.0.is_allocated()
}
#[inline]
pub fn into_borrowed(self) -> Result<&'borrow Path, Self> {
self.0.into_borrowed().map(Path::new).map_err(Self)
}
#[inline]
#[must_use]
pub const fn as_borrowed(&self) -> Option<&'borrow Path> {
match self.0.as_borrowed() {
Some(slice) => {
Some(unsafe { core::mem::transmute::<&OsStr, &Path>(slice) })
}
None => None,
}
}
#[allow(clippy::missing_const_for_fn)] #[must_use]
pub fn into_os_str(self) -> HipOsStr<'borrow, B> {
self.0
}
#[inline]
#[must_use]
pub fn as_path(&self) -> &Path {
Path::new(self.0.as_os_str())
}
#[inline]
#[must_use]
pub fn as_os_str(&self) -> &OsStr {
self.0.as_os_str()
}
#[inline]
#[must_use]
pub const fn inline_capacity() -> usize {
HipByt::<B>::inline_capacity()
}
#[inline]
#[must_use]
pub fn capacity(&self) -> usize {
self.0.capacity()
}
#[inline]
pub fn into_os_string(self) -> Result<OsString, Self> {
self.0.into_os_string().map_err(Self)
}
#[inline]
pub fn into_path_buf(self) -> Result<PathBuf, Self> {
self.0.into_os_string().map(PathBuf::from).map_err(Self)
}
#[inline]
#[must_use]
pub fn mutate(&mut self) -> RefMut<'_, 'borrow, B> {
let owned = self.take_path_buf();
RefMut {
result: self,
owned,
}
}
fn take_path_buf(&mut self) -> PathBuf {
PathBuf::from(self.0.take_os_string())
}
#[must_use]
pub fn into_owned(self) -> HipPath<'static, B> {
HipPath(self.0.into_owned())
}
#[inline]
pub fn into_str(self) -> Result<HipStr<'borrow, B>, Self> {
self.0.into_str().map_err(Self)
}
#[inline]
pub fn shrink_to_fit(&mut self) {
self.0.shrink_to_fit();
}
#[inline]
pub fn shrink_to(&mut self, min_capacity: usize) {
self.0.shrink_to(min_capacity);
}
}
impl<B> HipPath<'static, B>
where
B: Backend,
{
#[inline]
#[must_use]
pub const fn from_static(value: &'static str) -> Self {
Self(HipOsStr::from_static(value))
}
}
impl<B> Clone for HipPath<'_, B>
where
B: Backend,
{
#[inline]
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<B> Default for HipPath<'_, B>
where
B: Backend,
{
#[inline]
fn default() -> Self {
Self::new()
}
}
impl<B> Deref for HipPath<'_, B>
where
B: Backend,
{
type Target = Path;
#[inline]
fn deref(&self) -> &Self::Target {
self.as_path()
}
}
impl<B> Hash for HipPath<'_, B>
where
B: Backend,
{
#[inline]
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.as_path().hash(state);
}
}
impl<B> fmt::Debug for HipPath<'_, B>
where
B: Backend,
{
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self.as_path(), f)
}
}
pub struct RefMut<'a, 'borrow, B>
where
B: Backend,
{
result: &'a mut HipPath<'borrow, B>,
owned: PathBuf,
}
impl<B> fmt::Debug for RefMut<'_, '_, B>
where
B: Backend,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.owned.fmt(f)
}
}
impl<B> Drop for RefMut<'_, '_, B>
where
B: Backend,
{
fn drop(&mut self) {
let owned = core::mem::take(&mut self.owned);
*self.result = HipPath::from(owned);
}
}
impl<B> Deref for RefMut<'_, '_, B>
where
B: Backend,
{
type Target = PathBuf;
fn deref(&self) -> &Self::Target {
&self.owned
}
}
impl<B> DerefMut for RefMut<'_, '_, B>
where
B: Backend,
{
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.owned
}
}