diff --git a/src/esh/mod.rs b/src/esh/mod.rs deleted file mode 100644 index 8099c33..0000000 --- a/src/esh/mod.rs +++ /dev/null @@ -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 for ExecutionError { - fn from(e: CommandError) -> Self { - Self::ParseError(e) - } -} - -impl From 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> for Command { - type Error = CommandError; - - fn try_from(s: Captures) -> Result { - 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, - 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\w+)( (?P[\w\.]+))?") - .unwrap(); - static ref FILE_REGEX: Regex = Regex::new(r"(?P\d+) (?P[\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, - parent: Option>> -} - -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() - } - } -}