buf-fs 0.1.3

A buffer based, in-memory filesystem.
Documentation
use alloc::vec::Vec;
use relative_path::{RelativePath, RelativePathBuf};

use crate::FileSystem;

/// A file representation.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct File {
    /// The path of the file in the fs.
    pub path: RelativePathBuf,
    /// The byte contents of the file.
    pub contents: Vec<u8>,
    /// Flag indicating whether the file is newly created and hasn't existed before its current
    /// state for saving purposes.
    pub new: bool,
}

impl File {
    /// Creates a new file representation.
    pub fn new(path: RelativePathBuf, contents: Vec<u8>, new: bool) -> Self {
        Self {
            path,
            contents,
            new,
        }
    }

    /// Updates the byte contents of the file.
    pub fn update<F>(mut self, f: F) -> Self
    where
        F: FnOnce(&mut Vec<u8>),
    {
        f(&mut self.contents);
        self
    }

    /// Saves the file to the fs.
    pub fn save(self, fs: &mut FileSystem) -> anyhow::Result<()> {
        fs.save(self)
    }
}

/// A file path, without its contents.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct FilePath {
    /// The path of the file in the fs.
    pub path: RelativePathBuf,
    /// The length of the file in the fs.
    pub len: usize,
}

impl FilePath {
    /// Creates a new file path representation.
    pub fn new(path: RelativePathBuf, len: usize) -> Self {
        Self { path, len }
    }

    /// Opens the file with its contents from the fs.
    pub fn open(&self, fs: &mut FileSystem) -> anyhow::Result<File> {
        fs.open(&self.path)
    }
}

/// A directory representation
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Dir {
    /// The path of the directory in the fs.
    pub path: RelativePathBuf,
}

impl Dir {
    /// Creates a new directory path representation.
    pub fn new(path: RelativePathBuf) -> Self {
        Self { path }
    }

    /// Lists the contents of the directory in the fs.
    pub fn ls(&self, fs: &mut FileSystem) -> anyhow::Result<Vec<DirOrFile>> {
        fs.ls(&self.path)
    }
}

/// The contents of a directory, being a directory or a file.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum DirOrFile {
    /// A fs directory variant.
    Dir(Dir),
    /// A fs file variant.
    File(FilePath),
}

impl DirOrFile {
    /// Returns the underlying path of the entry.
    pub fn path(&self) -> &RelativePath {
        match self {
            DirOrFile::Dir(p) => p.path.as_relative_path(),
            DirOrFile::File(p) => p.path.as_relative_path(),
        }
    }

    /// Returns the directory, if the variant is in accordance.
    pub fn as_dir(&self) -> Option<&Dir> {
        match self {
            DirOrFile::Dir(dir) => Some(dir),
            _ => None,
        }
    }

    /// Returns the file path, if the variant is in accordance.
    pub fn as_file(&self) -> Option<&FilePath> {
        match self {
            DirOrFile::File(file) => Some(file),
            _ => None,
        }
    }
}

impl From<Dir> for DirOrFile {
    fn from(dir: Dir) -> Self {
        Self::Dir(dir)
    }
}

impl From<FilePath> for DirOrFile {
    fn from(file: FilePath) -> Self {
        Self::File(file)
    }
}