use std::{
borrow::Borrow,
ffi::OsStr,
fmt::{
Display,
Formatter,
Result as FmtResult,
},
ops::Deref,
path::{
Path as StdPath,
PathBuf,
},
};
use super::core::Path;
impl AsRef<StdPath> for Path {
fn as_ref(&self) -> &StdPath {
&self.0
}
}
impl Borrow<StdPath> for Path {
fn borrow(&self) -> &StdPath {
&self.0
}
}
impl Deref for Path {
type Target = StdPath;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Display for Path {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "{}", self.to_string_lossy())
}
}
impl From<&StdPath> for Path {
fn from(path: &StdPath) -> Self {
Self(path.to_path_buf())
}
}
impl From<&str> for Path {
fn from(path: &str) -> Self {
Self(PathBuf::from(path))
}
}
impl AsRef<OsStr> for Path {
fn as_ref(&self) -> &OsStr {
self.0.as_os_str()
}
}
impl From<String> for Path {
fn from(path: String) -> Self {
Self(PathBuf::from(path))
}
}
impl From<Path> for String {
fn from(path: Path) -> Self {
path.to_string_lossy().into_owned()
}
}
impl AsRef<str> for Path {
fn as_ref(&self) -> &str {
self.to_str().unwrap()
}
}
impl AsRef<PathBuf> for Path {
fn as_ref(&self) -> &PathBuf {
&self.0
}
}
impl From<Path> for PathBuf {
fn from(path: Path) -> Self {
path.0
}
}
impl AsRef<Path> for Path {
fn as_ref(&self) -> &Path {
self
}
}
#[cfg(test)]
mod tests {
use std::{
borrow::Borrow,
ffi::OsStr,
ops::Deref,
path::{
Path as StdPath,
PathBuf,
},
};
use super::Path;
#[test]
fn test_as_ref_std_path() {
let path = Path::new("/test/path");
let std_path: &StdPath = path.as_ref();
assert_eq!(std_path, StdPath::new("/test/path"));
}
#[test]
fn test_as_ref_self() {
let path = Path::new("/test/path");
let path_ref: &StdPath = path.as_ref();
assert_eq!(path_ref, StdPath::new("/test/path"));
}
#[test]
fn test_borrow() {
let path = Path::new("/test/path");
let borrowed: &StdPath = path.borrow();
assert_eq!(borrowed, StdPath::new("/test/path"));
}
#[test]
fn test_deref() {
let path = Path::new("/test/path");
let dereferenced: &StdPath = path.deref();
assert_eq!(dereferenced, StdPath::new("/test/path"));
}
#[test]
fn test_display() {
let path = Path::new("/test/path");
let display: String = path.to_string();
assert_eq!(display, "/test/path");
}
#[test]
fn test_display_format() {
let path = Path::new("/test/path");
assert_eq!(format!("{}", path), "/test/path");
}
#[test]
fn test_display_format_args() {
let path = Path::new("file.txt");
assert_eq!(format!("Path: {}", path), "Path: file.txt");
}
#[test]
fn test_from_std_path_ref() {
let std_path = std::path::Path::new("/test/path");
let path: Path = Path::from(std_path);
assert_eq!(path.to_str(), Some("/test/path"));
}
#[test]
fn test_from_pathbuf() {
let pathbuf = PathBuf::from("/test/path");
let path = Path::new(pathbuf);
assert_eq!(path.to_path_buf(), PathBuf::from("/test/path"));
}
#[test]
fn test_from_path_to_pathbuf() {
let path = Path::new("/test/path");
let pathbuf: PathBuf = PathBuf::from(path);
assert_eq!(pathbuf, PathBuf::from("/test/path"));
}
#[test]
fn test_to_string_lossy() {
let path = Path::new("/test/path");
let lost = path.to_string_lossy();
assert_eq!(lost, "/test/path");
}
#[test]
fn test_to_str() {
let path = Path::new("/test/path");
assert_eq!(path.to_str(), Some("/test/path"));
}
#[test]
fn test_to_str_unicode() {
let path = Path::new("/test/文件.txt");
assert_eq!(path.to_str(), Some("/test/文件.txt"));
}
#[test]
fn test_clone() {
let path = Path::new("/test/path");
let cloned = path.clone();
assert_eq!(path, cloned);
}
#[test]
fn test_clone_independence() {
let mut path1 = Path::new("/test/path");
let path2 = path1.clone();
path1 = Path::new("/other/path");
assert_eq!(path2.to_str(), Some("/test/path"));
assert_eq!(path1.to_str(), Some("/other/path"));
}
#[test]
fn test_eq() {
let path1 = Path::new("/test/path");
let path2 = Path::new("/test/path");
let path3 = Path::new("/other/path");
assert_eq!(path1, path2);
assert_ne!(path1, path3);
}
#[test]
fn test_eq_with_std_path() {
let path = Path::new("/test/path");
let std_path = StdPath::new("/test/path");
assert_eq!(path.as_path(), std_path);
}
#[test]
fn test_debug() {
let path = Path::new("/test/path");
let debug_str = format!("{:?}", path);
assert!(debug_str.contains("Path"));
assert!(debug_str.contains("/test/path"));
}
#[test]
fn test_hash() {
use std::{
collections::hash_map::DefaultHasher,
hash::{
Hash,
Hasher,
},
};
let path1 = Path::new("/test/path");
let path2 = Path::new("/test/path");
let path3 = Path::new("/other/path");
let mut hasher1 = DefaultHasher::new();
let mut hasher2 = DefaultHasher::new();
let mut hasher3 = DefaultHasher::new();
path1.hash(&mut hasher1);
path2.hash(&mut hasher2);
path3.hash(&mut hasher3);
assert_eq!(hasher1.finish(), hasher2.finish());
assert_ne!(hasher1.finish(), hasher3.finish());
}
#[test]
fn test_partial_eq_pathbuf() {
let path = Path::new("/test/path");
let pathbuf = PathBuf::from("/test/path");
assert_eq!(path.as_path(), pathbuf.as_path());
}
#[test]
fn test_as_os_str() {
let path = Path::new("/test/path");
let os_str = path.as_os_str();
assert_eq!(os_str, std::ffi::OsStr::new("/test/path"));
}
#[test]
fn test_as_ref_os_str() {
let path = Path::new("/test/path");
let os_str: &OsStr = path.as_ref();
assert_eq!(os_str, OsStr::new("/test/path"));
}
#[test]
fn test_from_str() {
let path: Path = Path::from("/test/path");
assert_eq!(path.to_str(), Some("/test/path"));
}
#[test]
fn test_from_string() {
let s = String::from("/test/path");
let path: Path = Path::from(s);
assert_eq!(path.to_str(), Some("/test/path"));
}
#[test]
fn test_to_string() {
let path = Path::new("/test/path");
let s: String = String::from(path);
assert_eq!(s, "/test/path");
}
#[test]
fn test_as_ref_str() {
let path = Path::new("/test/path");
let s: &str = path.as_ref();
assert_eq!(s, "/test/path");
}
#[test]
fn test_path_has_content() {
let path = Path::new("/test/path");
assert!(!path.to_str().unwrap().is_empty());
}
}