Compare commits

..

2 Commits

Author SHA1 Message Date
982dac721f
Merge remote-tracking branch 'origin/main' 2022-12-09 07:22:40 +01:00
df71a1f787
Removed esh 2022-12-09 07:22:34 +01:00

View File

@ -1,194 +0,0 @@
use std::borrow::BorrowMut;
use std::cell::RefCell;
use std::num::ParseIntError;
use std::ops::Deref;
use std::rc::Rc;
use std::str::FromStr;
use itertools::Itertools;
use lazy_static::lazy_static;
use regex::{Captures, Match, Regex};
use crate::esh::ExecutionError::DirectoryNotFoundError;
pub enum ExecutionError {
ParseError(CommandError),
DirectoryNotFoundError(String),
InvalidFileSize(ParseIntError)
}
impl From<CommandError> for ExecutionError {
fn from(e: CommandError) -> Self {
Self::ParseError(e)
}
}
impl From<ParseIntError> for ExecutionError {
fn from(e: ParseIntError) -> Self {
Self::InvalidFileSize(e)
}
}
pub enum CommandError {
UnknownCommand,
ArgumentError,
}
pub enum Command {
Ls,
CdParent,
CdRoot,
Cd(String),
}
impl TryFrom<Captures<'_>> for Command {
type Error = CommandError;
fn try_from(s: Captures) -> Result<Self, Self::Error> {
match s.name("cmd") {
Some(c) if c.as_str() == "ls" => Ok(Command::Ls),
Some(c) if c.as_str() == "cd" => match s.name("arg") {
None => Err(CommandError::ArgumentError),
Some(c) if c.as_str() == "/" => Ok(Command::CdRoot),
Some(c) if c.as_str() == ".." => Ok(Command::CdParent),
Some(c) => Ok(Command::Cd(c.as_str().into())),
},
_ => Err(CommandError::UnknownCommand)
}
}
}
pub struct Esh<'a> {
pub working_directory2: &'a Directory,
pub working_directory: RefCell<Directory>,
pub total_disk_space: usize
}
impl<'a> Esh<'a> {
pub fn execute(&mut self, line: &str) -> Result<(), ExecutionError> {
lazy_static! {
static ref COMMAND_REGEX: Regex = Regex::new(r"\$ (?P<cmd>\w+)( (?P<arg>[\w\.]+))?")
.unwrap();
static ref FILE_REGEX: Regex = Regex::new(r"(?P<size>\d+) (?P<name>[\w\.]+)")
.unwrap();
}
if let Some(captures) = COMMAND_REGEX.captures(line) {
let command = captures.try_into()?;
self.execute_command(command)?;
} else if let Some(captures) = FILE_REGEX.captures(line) {
let size = captures.name("size").unwrap().as_str().parse()?;
let file = DirectoryEntry::File {
size,
name: captures.name("name").unwrap().as_str().into()
};
//self.working_directory.entries.push(file);
}
Ok(())
}
fn execute_command(&mut self, command: Command) -> Result<(), ExecutionError> {
match command {
Command::Ls => Ok(()),
Command::CdRoot => {
while let Some(wd) = &self.working_directory.borrow().parent {
self.working_directory.replace(wd.into_inner());
}/*
while let Some(wd) = &self.working_directory.into_inner().parent {
self.working_directory = wd;
}*/
Ok(())
},
Command::CdParent => {
/*
if let Some(wd) = &self.working_directory.parent {
self.working_directory = wd;
Ok(())
}*/
if let Some(wd) = &self.working_directory.borrow().parent {
self.working_directory.replace(wd.into_inner());
Ok(())
} else {
Err(DirectoryNotFoundError(
format!("{}/../", self.working_directory.borrow().name)
))
}
},
Command::Cd(dir) => {
if let Some(child) = self.working_directory.into_inner().subfolder(&dir) {
//self.working_directory = RefCell::from()
todo!();
Ok(())
} else {
Err(DirectoryNotFoundError(
format!("{}/{}/", self.working_directory.name, dir)
))
}
}
}
}
}
/*
impl<'a> Default for Esh<'a> {
fn default() -> Self {
let d: &'static Directory = &Directory::root();
Esh {
working_directory: d,
total_disk_space: 70000000
}
}
}
*/
pub enum DirectoryEntry {
File { size: usize, name: String },
Directory(Directory)
}
pub struct Directory {
name: String,
entries: Vec<DirectoryEntry>,
parent: Option<Rc<RefCell<Directory>>>
}
impl Directory {
pub fn size(&self) -> usize {
self.entries.iter().map(|e|e.size()).sum()
}
pub fn root() -> Self {
Self {
name: "/".into(),
entries: vec![],
parent: None
}
}
pub fn subfolder(&self, dir: &str) -> Option<&Directory> {
self.entries
.iter()
.flat_map(|e| {
match e {
DirectoryEntry::Directory(d) if d.name == dir => Some(d),
_ => None
}
})
.next()
}
}
impl Default for Directory {
fn default() -> Self { Directory::root() }
}
impl DirectoryEntry {
pub fn size(&self) -> usize {
match self {
DirectoryEntry::File { size, name } => *size,
DirectoryEntry::Directory(d) => d.size()
}
}
pub fn name(&self) -> String {
match &self {
DirectoryEntry::File { size, name } => name.into(),
DirectoryEntry::Directory(d) => (*d.name).into()
}
}
}