use alloc::{borrow::Cow, rc::Rc, sync::Arc};
use core::{convert::Infallible, str::FromStr};
use std::{
ffi::{OsStr, OsString},
path::{Path, PathBuf},
};
use crate::flex::{
FlexStr, ImmutableBytes, RefCounted, RefCountedMut, partial_eq_impl, ref_counted_mut_impl,
};
use flexstr_support::StringToFromBytes;
pub type LocalPath = FlexStr<'static, Path, Rc<Path>>;
pub type SharedPath = FlexStr<'static, Path, Arc<Path>>;
pub type LocalPathRef<'s> = FlexStr<'s, Path, Rc<Path>>;
pub type SharedPathRef<'s> = FlexStr<'s, Path, Arc<Path>>;
const _: () = assert!(
size_of::<Option<LocalPath>>() <= size_of::<PathBuf>(),
"Option<LocalPath> must be less than or equal to the size of PathBuf"
);
const _: () = assert!(
size_of::<Option<SharedPath>>() <= size_of::<PathBuf>(),
"Option<SharedPath> must be less than or equal to the size of PathBuf"
);
impl ImmutableBytes for Path {}
ref_counted_mut_impl!(Path);
impl<'s, R: RefCounted<Path>> From<PathBuf> for FlexStr<'s, Path, R> {
fn from(p: PathBuf) -> Self {
FlexStr::from_owned(p)
}
}
impl<'s, R: RefCounted<Path>> From<String> for FlexStr<'s, Path, R> {
fn from(s: String) -> Self {
FlexStr::from_owned(s.into())
}
}
impl<'s, R: RefCounted<Path>> From<OsString> for FlexStr<'s, Path, R> {
fn from(s: OsString) -> Self {
FlexStr::from_owned(s.into())
}
}
impl<'s, R: RefCounted<Path>> From<&'s str> for FlexStr<'s, Path, R> {
fn from(s: &'s str) -> Self {
FlexStr::from_borrowed(Path::new(s))
}
}
impl<'s, R: RefCounted<Path>> From<&'s OsStr> for FlexStr<'s, Path, R> {
fn from(s: &'s OsStr) -> Self {
FlexStr::from_borrowed(Path::new(s))
}
}
partial_eq_impl!(Path, Path);
partial_eq_impl!(&Path, Path);
partial_eq_impl!(PathBuf, Path);
partial_eq_impl!(Cow<'s, Path>, Path);
impl<'s, S: ?Sized + StringToFromBytes, R: RefCounted<S>> AsRef<Path> for FlexStr<'s, S, R>
where
S: AsRef<Path>,
{
fn as_ref(&self) -> &Path {
self.as_ref_type().as_ref()
}
}
impl<R: RefCounted<Path>> FromStr for FlexStr<'static, Path, R> {
type Err = Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(FlexStr::from_borrowed(Path::new(s)).into_owned())
}
}