Skip to content

Commit

Permalink
state
Browse files Browse the repository at this point in the history
  • Loading branch information
X39 committed Sep 11, 2023
1 parent d6e1c46 commit 2293b89
Show file tree
Hide file tree
Showing 8 changed files with 965 additions and 124 deletions.
2 changes: 2 additions & 0 deletions src/fileio/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
mod mount;
mod virtual_file_system;
mod mounts;
mod path;

fn main() {
println!("Hello, world!");
}
32 changes: 27 additions & 5 deletions src/fileio/src/mount.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::fmt::{Debug, Display, Formatter};
use crate::path::Path;

pub type PhysicalPath = String;
pub type VirtualPath = String;
pub type PhysicalPath = Path;
pub type VirtualPath = Path;

#[derive(Debug, PartialEq, Eq, )]
pub enum PropertyError {
Expand Down Expand Up @@ -41,7 +42,15 @@ impl Display for OpenError {
impl std::error::Error for OpenError {}

#[derive(Debug, PartialEq, Eq)]
pub enum IOError {}
pub enum IOError {
ReadFailed,
WriteFailed,
SeekFailed,
PositionFailed,
FlushFailed,
FailedToGetFileName,
PathConversionFailed,
}

impl Display for IOError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
Expand All @@ -55,7 +64,7 @@ impl std::error::Error for IOError {}
pub enum SeekFrom {
Start(u64),
Current(i64),
End(u64),
End(i64),
}

pub trait File {
Expand All @@ -73,7 +82,8 @@ pub trait FileInfo {
fn is_file(&self) -> bool;
fn length(&self) -> Result<u64, IOError>;
fn name(&self) -> Result<String, IOError>;
fn path(&self) -> Result<VirtualPath, IOError>;
fn virtual_path(&self) -> Result<VirtualPath, IOError>;
fn physical_path(&self) -> Result<PhysicalPath, IOError>;
}

#[derive(Debug, PartialEq, Eq, Clone, Hash)]
Expand Down Expand Up @@ -235,6 +245,18 @@ pub trait Mount {
* The file or an error if the file cannot be found.
*/
fn get_file_info(&self, path: &VirtualPath) -> Result<Box<dyn FileInfo>, IOError>;

/**
* Gets information about a directory.
* If the directory does not exist, an error will be returned.
*
* # Arguments
* - `path` The path to the directory to get information about.
*
* # Returns
* The directory or an error if the directory cannot be found.
*/
fn iter_directory(&self, path: &VirtualPath, recursive: bool) -> Result<Box<dyn Iterator<Item=Box<dyn FileInfo>>>, IOError>;
}

impl Debug for dyn Mount {
Expand Down
4 changes: 3 additions & 1 deletion src/fileio/src/mounts.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod empty;
mod filesystem;

pub use self::empty::*;
pub use self::empty::*;
pub use self::filesystem::*;
13 changes: 11 additions & 2 deletions src/fileio/src/mounts/empty.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::mount::{File, FileInfo, IOError, Mount, MountProperty, OpenError, PhysicalPath, PropertyError, ResolveError, SeekFrom, VirtualPath};
use crate::path::Path;

#[derive(Debug, PartialEq, Eq)]
struct EmptyFile {}
Expand Down Expand Up @@ -50,8 +51,12 @@ impl FileInfo for EmptyFile {
Ok(String::new())
}

fn path(&self) -> Result<VirtualPath, IOError> {
Ok(String::new())
fn virtual_path(&self) -> Result<VirtualPath, IOError> {
Ok(Path::empty())
}

fn physical_path(&self) -> Result<PhysicalPath, IOError> {
Ok(Path::empty())
}
}

Expand Down Expand Up @@ -127,6 +132,10 @@ impl Mount for Empty {
fn get_file_info(&self, path: &VirtualPath) -> Result<Box<dyn FileInfo>, IOError> {
Ok(Box::new(EmptyFile {}))
}

fn iter_directory(&self, path: &VirtualPath, recursive: bool) -> Result<Box<dyn Iterator<Item=Box<dyn FileInfo>>>, IOError> {
Ok(Box::new(std::iter::empty()))
}
}


Expand Down
191 changes: 191 additions & 0 deletions src/fileio/src/mounts/filesystem.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
use std::io::{Read, Seek, Write};
use std::io::SeekFrom::{Current, End, Start};
use crate::mount::{File, FileInfo, IOError, Mount, MountProperty, OpenError, PhysicalPath, PropertyError, ResolveError, SeekFrom, VirtualPath};

struct FileSystemFile {
path: PhysicalPath,
file: std::fs::File,
}

impl File for FileSystemFile {
fn can_read(&self) -> bool {
true
}

fn can_write(&self) -> bool {
true
}

fn read(&mut self, buf: &mut [u8]) -> Result<usize, IOError> {
let result = self.file.read(buf);
match result {
Ok(size) => Ok(size),
Err(_) => Err(IOError::ReadFailed),
}
}

fn write(&mut self, buf: &[u8]) -> Result<(), IOError> {
let result = self.file.write(buf);
match result {
Ok(_) => Ok(()),
Err(_) => Err(IOError::WriteFailed),
}
}

fn seek(&mut self, pos: SeekFrom) -> Result<(), IOError> {
let result = self.file.seek(match pos {
SeekFrom::Start(start) => Start(start),
SeekFrom::Current(current) => Current(current),
SeekFrom::End(end) => End(end),
});
match result {
Ok(_) => Ok(()),
Err(_) => Err(IOError::SeekFailed),
}
}

fn position(&mut self) -> Result<u64, IOError> {
let result = self.file.stream_position();
match result {
Ok(pos) => Ok(pos),
Err(_) => Err(IOError::PositionFailed),
}
}

fn flush(&mut self) -> Result<(), IOError> {
let result = self.file.flush();
match result {
Ok(_) => Ok(()),
Err(_) => Err(IOError::FlushFailed),
}
}
}

#[derive(Debug, PartialEq, Eq)]
struct FileSystemFileInfo {
virtual_path: VirtualPath,
physical_path: PhysicalPath,
}
impl FileInfo for FileSystemFileInfo {
fn is_directory(&self) -> bool {
let result = std::fs::metadata(&self.physical_path);
match result {
Ok(metadata) => metadata.is_dir(),
Err(_) => false,
}
}

fn is_file(&self) -> bool {
let result = std::fs::metadata(&self.physical_path);
match result {
Ok(metadata) => metadata.is_file(),
Err(_) => false,
}
}

fn length(&self) -> Result<u64, IOError> {
let result = std::fs::metadata(&self.physical_path);
match result {
Ok(metadata) => Ok(metadata.len()),
Err(_) => Err(IOError::ReadFailed),
}
}

fn name(&self) -> Result<String, IOError> {
Ok(self.physical_path.last_segment().to_string())
}

fn virtual_path(&self) -> Result<VirtualPath, IOError> {
Ok(self.virtual_path.clone())
}
fn physical_path(&self) -> Result<PhysicalPath, IOError> {
Ok(self.physical_path.clone())
}
}

#[derive(Debug, PartialEq, Eq)]
pub struct FileSystem {
properties: Vec<MountProperty>,
}

impl FileSystem {
pub fn new() -> FileSystem {
FileSystem { properties: vec![] }
}
}

impl Mount for FileSystem {
fn get_properties(&self) -> Vec<MountProperty> {
self.properties.clone()
}

fn set_property(&mut self, name: String, value: String) -> Result<(), PropertyError> {
if let Some(property) = self.properties.iter_mut().find(|p| p.name == name) {
property.value = value;
} else {
self.properties.push(MountProperty { name, value });
}
Ok(())
}

fn get_property(&self, name: String) -> Result<String, PropertyError> {
if let Some(property) = self.properties.iter().find(|p| p.name == name) {
Ok(property.value.clone())
} else {
Err(PropertyError::NotFound)
}
}

fn can_read(&self) -> bool {
true
}

fn can_write(&self) -> bool {
true
}

fn to_virtual_path(&self, path: &PhysicalPath) -> Result<VirtualPath, ResolveError> {
todo!()
}

fn to_physical_path(&self, path: &VirtualPath) -> Result<PhysicalPath, ResolveError> {
todo!()
}

fn open_read(&self, path: &VirtualPath) -> Result<Box<dyn File>, OpenError> {
todo!()
}

fn open_write(&self, path: &VirtualPath) -> Result<Box<dyn File>, OpenError> {
todo!()
}

fn delete(&self, path: &VirtualPath) -> Result<(), IOError> {
todo!()
}

fn create_directory(&self, path: &VirtualPath) -> Result<Box<dyn FileInfo>, IOError> {
todo!()
}

fn create_file(&self, path: &VirtualPath) -> Result<Box<dyn FileInfo>, IOError> {
todo!()
}

fn get_file_info(&self, path: &VirtualPath) -> Result<Box<dyn FileInfo>, IOError> {
todo!()
}

fn iter_directory(&self, path: &VirtualPath, recursive: bool) -> Result<Box<dyn Iterator<Item=Box<dyn FileInfo>>>, IOError> {
todo!()
}
}


#[cfg(test)]
mod tests {
use tracing_test::traced_test;
use crate::mount::Mount;
use crate::mounts::Empty;

}
Loading

0 comments on commit 2293b89

Please sign in to comment.