From c4df3d18c708c2916321a764cdc9e74d2c23d884 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Sun, 3 Nov 2024 17:49:34 +0000 Subject: [PATCH] feat(fs): add .path(path).soft_link(other), .path(path).is_link() --- src/fs/path.rs | 40 ++++++++++++++++++++++++++++++++++++++++ tests/fs.rs | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/src/fs/path.rs b/src/fs/path.rs index 581f9e3..9325971 100644 --- a/src/fs/path.rs +++ b/src/fs/path.rs @@ -243,6 +243,46 @@ impl<'base, 'path, T: PathType> PathReal<'base, 'path, T> { self.check_error()?; std::fs::metadata(self.as_pathbuf()).map_err(Error::Io) } + + /// Creates a symbolic link to a path. + /// + /// Wrapper for [std::os::unix::fs::symlink] + /// + /// ``` + /// # use kxio::fs::Result; + /// # fn main() -> Result<()> { + /// let fs = kxio::fs::temp()?; + /// let src_path = fs.base().join("foo"); + /// let src = fs.file(&src_path); + /// # src.write("bar")?; + /// let link_path = fs.base().join("bar"); + /// let link = fs.path(&link_path); + /// src.soft_link(&link)?; + /// # Ok(()) + /// # } + /// ``` + pub fn soft_link(&self, link: &PathReal<'_, '_, PathMarker>) -> Result<()> { + self.check_error()?; + std::os::unix::fs::symlink(self.as_pathbuf(), link.as_pathbuf()).map_err(Error::Io) + } + + /// Returns true if the path is a symbolic link. + /// + /// ``` + /// # use kxio::fs::Result; + /// # fn main() -> Result<()> { + /// let fs = kxio::fs::temp()?; + /// let path = fs.base().join("foo"); + /// let dir = fs.dir(&path); + /// # dir.create()?; + /// if dir.is_link()? { /* ... */ } + /// # Ok(()) + /// # } + /// ``` + pub fn is_link(&self) -> Result { + self.check_error()?; + Ok(self.as_pathbuf().is_symlink()) + } } impl<'base, 'path> From> for PathBuf { fn from(path: PathReal) -> Self { diff --git a/tests/fs.rs b/tests/fs.rs index a6b76a0..7d947de 100644 --- a/tests/fs.rs +++ b/tests/fs.rs @@ -299,6 +299,42 @@ mod path { mod file { use super::*; + // // test for reading the symlink metadata + // #[test] + // fn symlink_metadata() -> TestResult { + // let fs = fs::temp().expect("temp fs"); + // let file_path = fs.base().join("foo"); + // let file = fs.file(&file_path); + // file.write("bar").expect("write"); + // let link_path = fs.base().join("bar"); + // let link = fs.path(&link_path); + // file.soft_link(&link).expect("soft_link"); + // let md = link.symlink_metadata().expect("symlink metadata"); + // assert!(md.is_file()); + // Ok(()) + // } + + #[test] + fn create_soft_link() -> TestResult { + let fs = fs::temp().expect("temp fs"); + + let file_path = fs.base().join("foo"); + let file = fs.file(&file_path); + file.write("content").expect("write"); + + let link_path = fs.base().join("bar"); + let link = fs.path(&link_path); + file.soft_link(&link).expect("soft_link"); + + let exists = link.exists().expect("exists"); + assert!(exists); + + let is_link = link.is_link().expect("is_link"); + assert!(is_link); + + Ok(()) + } + #[test] fn create_hard_link() -> TestResult { let fs = fs::temp().expect("temp fs");