Преглед изворни кода

Almost finished shell. cd working.

Still using unwraps :|
themultiplexer пре 8 година
родитељ
комит
c111556cdc
3 измењених фајлова са 92 додато и 64 уклоњено
  1. 38
    4
      hw6/task2/src/command.rs
  2. 8
    4
      hw6/task2/src/main.rs
  3. 46
    56
      hw6/task2/src/shell.rs

+ 38
- 4
hw6/task2/src/command.rs Прегледај датотеку

@@ -1,20 +1,54 @@
1 1
 use std::ffi::OsString;
2 2
 use std::str::FromStr;
3
+use std::env;
4
+use std::path::Path;
3 5
 
4
-enum Command {
6
+pub enum Command {
5 7
     Empty,
6 8
     Exit,
7 9
     Cd(Option<OsString>),
8 10
 }
9 11
 
10
-impl Command {}
11
-
12
-struct CommandNotFoundError();
12
+pub struct CommandNotFoundError;
13 13
 
14 14
 impl FromStr for Command {
15 15
 
16 16
     type Err = CommandNotFoundError;
17 17
     fn from_str(s: &str) -> Result<Self, Self::Err> {
18 18
 
19
+        let mut parts = s.split_whitespace();
20
+
21
+        match parts.next() {
22
+            Some("exit") => return Ok(Command::Exit),
23
+            Some("cd") => return Ok(Command::parse_cd(parts.next())),
24
+            Some(_) => return Ok(Command::Empty),
25
+            None => return Err(CommandNotFoundError),
26
+        }
27
+    }
28
+
29
+}
30
+
31
+impl Command {
32
+    pub fn parse_cd(cmd: Option<&str>) -> Self {
33
+        match cmd {
34
+            None => Command::Cd(None),
35
+            Some(dest) => Command::Cd(Some(OsString::from(dest))),
36
+        }
37
+    }
38
+
39
+    pub fn exec_cd(&self) {
40
+        if let Command::Cd(None) = *self  {
41
+            let home = env::home_dir().unwrap();
42
+            let home_path = home.as_path();
43
+            env::set_current_dir(home_path);
44
+        }
45
+
46
+        if let Command::Cd(Some(ref path)) = *self {
47
+            match path.to_str() {
48
+                Some(_) => {env::set_current_dir(path);},
49
+                None => {},
50
+            }
51
+
52
+        }
19 53
     }
20 54
 }

+ 8
- 4
hw6/task2/src/main.rs Прегледај датотеку

@@ -1,13 +1,17 @@
1 1
 use std::process;
2 2
 use shell::Shell;
3
+use std::io;
3 4
 
4
-mod shell;
5 5
 mod command;
6
+mod shell;
7
+
6 8
 
7 9
 fn main() {
8
-    let reader = shell::R;
9
-    let writer = shell::W;
10
-    let mut s = Shell::new(reader, writer, "schell".to_string());
10
+    let stdin = io::stdin();
11
+
12
+    let stdout = io::stdout();
13
+
14
+    let mut s = Shell::new(stdin.lock(), stdout.lock(), "schell".to_string());
11 15
     match s.start() {
12 16
         Ok(_) => process::exit(0),
13 17
         Err(_) => process::exit(1),

+ 46
- 56
hw6/task2/src/shell.rs Прегледај датотеку

@@ -1,20 +1,17 @@
1
-use std::io;
2
-use std::io::prelude::*;
3 1
 use std::io::BufRead;
4
-use std::io::Read;
2
+use std::io::Write;
3
+use command::*;
4
+use std::str::FromStr;
5
+use std::env;
5 6
 
6
-
7
-pub struct R;
8
-pub struct W;
9
-
10
-pub struct Shell<R, W> {
7
+pub struct Shell<R:BufRead, W:Write> {
11 8
     pub reader: R,
12 9
     pub writer: W,
13 10
     pub should_exit: bool,
14 11
     pub name: String,
15 12
 }
16 13
 
17
-impl Shell<R, W> {
14
+impl <R:BufRead, W:Write> Shell<R, W> {
18 15
     /// Creates a new Shell.
19 16
     pub fn new(input: R, output: W, name: String) -> Self {
20 17
         Shell {
@@ -25,65 +22,58 @@ impl Shell<R, W> {
25 22
         }
26 23
     }
27 24
     /// Initializes the Shell Loop
28
-    pub fn start<'a>(&self) -> Result<(), &'a str> {
29
-        self.shell_loop();
30
-        Ok(())
25
+    pub fn start(&mut self) -> Result<(), &str> {
26
+        self.shell_loop()
31 27
     }
32 28
 
33 29
     /// Waits for user inputs.
34
-    fn shell_loop(&self) -> Result<(),()> {
35
-        loop {
30
+    fn shell_loop(&mut self) -> Result<(),&str> {
31
+        while !self.should_exit {
32
+            if let Ok(line) = self.prompt() {
33
+                Command::from_str(&line).and_then(|cmd| self.run(cmd));
34
+            }
36 35
         }
36
+        Ok(())
37 37
     }
38 38
 
39
-    /*
40 39
     /// Prints the shell prompt.
41
-    fn prompt() -> Result<Option, &str> {
40
+    fn prompt (&mut self) -> Result<String, &str> {
41
+
42
+
43
+        match env::current_dir() {
44
+            Ok(pwd) => {
45
+                self.writer.write(format!("{} {} > ", self.name, pwd.display()).as_bytes());
46
+                self.writer.flush();
47
+
48
+                let mut line: String = String::new();
49
+                let read_result = self.reader.read_line(&mut line);
50
+                match read_result {
51
+                    Ok(_) => {
52
+                        Ok(line)
53
+                    },
54
+                    Err(_) => {
55
+                        Err("Error reading.")
56
+                    },
57
+                }
58
+            },
59
+            Err(_) => return Err("Path Error"),
60
+        }
42 61
     }
43 62
     /// Runs a command.
44
-    fn run(&str) {
45
-    }
46
-
47
-    */
48
-}
49
-
50
-
51
-impl Read for R {
52
-    fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
53
-        let stdin = io::stdin();
54
-        let mut stdin = stdin.lock();
55
-
56
-
57
-        let buffer = stdin.read(buf);
58
-
59
-        match buffer {
60
-            Ok(x) => {
61
-                println!("{} ||| {:?}", x, buffer);
62
-                stdin.consume(x);
63
-                Ok(x)
63
+    fn run(&mut self, command: Command) -> Result<(), CommandNotFoundError>{
64
+
65
+        match command {
66
+            Command::Empty => {
67
+                self.writer.write("Command not found\n".as_bytes());
68
+                self.writer.flush();
69
+                return Err(CommandNotFoundError);},
70
+            Command::Exit => self.should_exit = true,
71
+            Command::Cd(_) => {
72
+                command.exec_cd();
64 73
             },
65
-            Err(_) => Err(io::Error::new(io::ErrorKind::InvalidInput, "jhrthhzruzkikz")),
66 74
         }
67
-    }
68
-}
69
-
70
-impl BufRead for R {
71
-
72
-    fn fill_buf(&mut self) -> Result<&[u8], io::Error> {
73
-        Ok(&[11])
75
+        Ok(())
74 76
     }
75 77
 
76
-    fn consume(&mut self, amt: usize) {
77
-        let mut buffer = self.fill_buf;
78
-        if buffer.len <= amt {
79
-
80
-        }
81
-    }
82 78
 }
83 79
 
84
-impl Write for W {
85
-    fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
86
-    }
87
-    fn flush(&mut self) -> Result<(),  io::Error> {
88
-    }
89
-}

Loading…
Откажи
Сачувај