use std ::path ::Path;
use std ::collections ::HashMap;
use crate ::Error;
pub trait FileSystem
{
fn read( &self, path: &Path ) -> Result< String, Error >;
fn write( &mut self, path: &Path, content: &str ) -> Result< (), Error >;
fn exists( &self, path: &Path ) -> bool;
}
#[ derive( Debug, Default ) ]
pub struct MemoryFileSystem
{
files: HashMap< std ::path ::PathBuf, String >,
}
impl MemoryFileSystem
{
#[must_use]
pub fn new() -> Self
{
Self
{
files: HashMap ::new(),
}
}
}
impl FileSystem for MemoryFileSystem
{
fn read( &self, path: &Path ) -> Result< String, Error >
{
self
.files
.get( path )
.cloned()
.ok_or_else( ||
{
Error ::Fs
(
std ::io ::Error ::new
(
std ::io ::ErrorKind ::NotFound,
format!( "File not found: {}", path.display() )
)
)
})
}
fn write( &mut self, path: &Path, content: &str ) -> Result< (), Error >
{
self.files.insert( path.to_path_buf(), content.to_string() );
Ok(())
}
fn exists( &self, path: &Path ) -> bool
{
self.files.contains_key( path )
}
}
#[ derive( Debug ) ]
pub struct RealFileSystem;
impl RealFileSystem
{
#[must_use]
pub fn new() -> Self
{
Self
}
}
impl Default for RealFileSystem
{
fn default() -> Self
{
Self ::new()
}
}
impl FileSystem for RealFileSystem
{
fn read( &self, path: &Path ) -> Result< String, Error >
{
std ::fs ::read_to_string( path ).map_err( Error ::from )
}
fn write( &mut self, path: &Path, content: &str ) -> Result< (), Error >
{
if let Some( parent ) = path.parent()
{
std ::fs ::create_dir_all( parent )?;
}
std ::fs ::write( path, content ).map_err( Error ::from )
}
fn exists( &self, path: &Path ) -> bool
{
path.exists()
}
}