No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

shell.rs 2.1KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. use std::io::BufRead;
  2. use std::io::Write;
  3. use command::*;
  4. use std::str::FromStr;
  5. use std::env;
  6. pub struct Shell<R:BufRead, W:Write> {
  7. pub reader: R,
  8. pub writer: W,
  9. pub should_exit: bool,
  10. pub name: String,
  11. }
  12. impl <R:BufRead, W:Write> Shell<R, W> {
  13. /// Creates a new Shell.
  14. pub fn new(input: R, output: W, name: String) -> Self {
  15. Shell {
  16. reader : input,
  17. writer : output,
  18. should_exit : false,
  19. name : name,
  20. }
  21. }
  22. /// Initializes the Shell Loop
  23. pub fn start(&mut self) -> Result<(), &str> {
  24. self.shell_loop()
  25. }
  26. /// Waits for user inputs.
  27. fn shell_loop(&mut self) -> Result<(),&str> {
  28. while !self.should_exit {
  29. if let Ok(line) = self.prompt() {
  30. Command::from_str(&line).and_then(|cmd| self.run(cmd));
  31. }
  32. }
  33. Ok(())
  34. }
  35. /// Prints the shell prompt.
  36. fn prompt (&mut self) -> Result<String, &str> {
  37. match env::current_dir() {
  38. Ok(pwd) => {
  39. self.writer.write(format!("{} {} > ", self.name, pwd.display()).as_bytes());
  40. self.writer.flush();
  41. let mut line: String = String::new();
  42. let read_result = self.reader.read_line(&mut line);
  43. match read_result {
  44. Ok(_) => {
  45. Ok(line)
  46. },
  47. Err(_) => {
  48. Err("Error reading.")
  49. },
  50. }
  51. },
  52. Err(_) => return Err("Path Error"),
  53. }
  54. }
  55. /// Runs a command.
  56. fn run(&mut self, command: Command) -> Result<(), CommandNotFoundError>{
  57. match command {
  58. Command::Empty => {
  59. self.writer.write("Command not found\n".as_bytes());
  60. self.writer.flush();
  61. return Err(CommandNotFoundError);},
  62. Command::Exit => self.should_exit = true,
  63. Command::Cd(_) => {
  64. command.exec_cd();
  65. },
  66. }
  67. Ok(())
  68. }
  69. }