kxio 3.2.0

Provides injectable Filesystem and Network resources to make code more testable
Documentation
use std::fmt::Display;

//
use crate::fs::Result;

use super::{reader::Reader, Error, FileHandle, FileMarker, PathHandle, PathMarker, PathReal};

impl FileHandle {
    /// Returns a [Reader] for the file.
    ///
    /// ```
    /// # fn try_main() -> kxio::fs::Result<()> {
    /// let fs = kxio::fs::temp()?;
    /// let path = fs.base().join("foo").join("bar");
    /// let file = fs.file(&path);
    /// let reader = file.reader()?;
    /// # Ok(())
    /// # }
    /// ```
    #[tracing::instrument]
    pub fn reader(&self) -> Result<Reader> {
        self.check_error()?;
        Reader::new(&self.as_pathbuf())
    }

    /// Writes a slice as the entire contents of a file.
    ///
    /// Wrapper for [std::fs::write]
    ///
    /// ```
    /// # fn try_main() -> kxio::fs::Result<()> {
    /// let fs = kxio::fs::temp()?;
    /// let path = fs.base().join("foo").join("bar");
    /// let file = fs.file(&path);
    /// file.write("new file contents")?;
    /// # Ok(())
    /// # }
    /// ```
    #[tracing::instrument(skip_all)]
    pub fn write<C: AsRef<[u8]>>(&self, contents: C) -> Result<()> {
        self.check_error()?;
        let file = self.as_pathbuf();
        tracing::debug!(?file, "std::fs::write");
        std::fs::write(file, contents).map_err(Error::Io)
    }

    /// Copies the contents of a file to another file.
    ///
    /// Wrapper for [std::fs::copy]
    ///
    /// ```
    /// # fn try_main() -> kxio::fs::Result<()> {
    /// let fs = kxio::fs::temp()?;
    /// let src_path = fs.base().join("foo");
    /// let dest_path = fs.base().join("bar");
    /// let src = fs.file(&src_path);
    /// # fs.file(&dest_path).write("new file contents")?;
    /// let dest = fs.file(&dest_path);
    /// src.copy(&dest)?;
    /// # Ok(())
    /// # }
    /// ```
    #[tracing::instrument]
    pub fn copy(&self, dest: &FileHandle) -> Result<u64> {
        self.check_error()?;
        let from = self.as_pathbuf();
        let to = dest.as_pathbuf();
        tracing::debug!(?from, ?to, "std::fs::copy");
        std::fs::copy(from, to).map_err(Error::Io)
    }

    /// Removes a file.
    ///
    /// Wrapper for [std::fs::remove_file]
    ///
    /// ```
    /// # fn try_main() -> kxio::fs::Result<()> {
    /// let fs = kxio::fs::temp()?;
    /// let path = fs.base().join("foo");
    /// let file = fs.file(&path);
    /// file.remove()?;
    /// # Ok(())
    /// # }
    /// ```
    #[tracing::instrument]
    pub fn remove(&self) -> Result<()> {
        self.check_error()?;
        let file = self.as_pathbuf();
        tracing::debug!(?file, "std::fs::remove_file");
        std::fs::remove_file(file).map_err(Error::Io)
    }

    /// Creates a hard link on the filesystem.
    ///
    /// Wrapper for [std::fs::hard_link]
    ///
    /// ```
    /// # 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 dst_path = fs.base().join("bar");
    /// let dst = fs.file(&dst_path);
    /// src.hard_link(&dst)?;
    /// #    Ok(())
    /// # }
    /// ```
    #[tracing::instrument]
    pub fn hard_link(&self, dest: &FileHandle) -> Result<()> {
        self.check_error()?;
        let original = self.as_pathbuf();
        let link = dest.as_pathbuf();
        tracing::debug!(?original, ?link, "std::fs::hard_link");
        std::fs::hard_link(original, link).map_err(Error::Io)
    }
}
impl TryFrom<PathHandle<PathMarker>> for FileHandle {
    type Error = crate::fs::Error;

    fn try_from(path: PathHandle<PathMarker>) -> std::result::Result<Self, Self::Error> {
        match path.as_file() {
            Ok(Some(dir)) => Ok(dir.clone()),
            Ok(None) => Err(crate::fs::Error::NotAFile {
                path: path.as_pathbuf(),
            }),
            Err(err) => Err(err),
        }
    }
}

impl Display for PathReal<FileMarker> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.as_pathbuf().display())
    }
}