1use crate::line_reader::LineReader;
2use crate::scope::Scope;
3use crate::Line;
4use crate::{line_writer::LineWriter, result::Action, CommandResult};
5use std::fmt::Debug;
6
7#[derive(Debug)]
10pub struct Runner<R: LineReader, W: LineWriter> {
11 reader: R,
12 writer: W,
13}
14
15impl<R: LineReader, W: LineWriter> Runner<R, W> {
16 pub fn new(reader: R, writer: W) -> Self {
18 Runner { reader, writer }
19 }
20
21 pub fn run<S: Scope>(&mut self, scope: &mut S) -> CommandResult {
23 let mut result = self.run_scope(scope);
24
25 while let Ok(Action::NewScope(mut sub_scope)) = result {
26 result = self.run_scope(sub_scope.as_mut());
27 }
28
29 result
30 }
31
32 fn run_scope(&mut self, scope: &mut dyn Scope) -> CommandResult {
35 scope.before_loop();
36
37 let mut last_result = Ok(Action::Done);
38 let commands = scope.commands();
39
40 while let Ok(Action::Done) = last_result {
41 last_result = match self.reader.read_line(scope.prompt().as_ref()) {
42 Err(error) => Err(error),
43 Ok(line_string) => {
44 let line = Line::try_parse(line_string.as_ref());
45 match line {
46 Err(error) => Err(error),
47 Ok(line) => {
48 let line = scope.before_command(line);
49
50 let result = match commands.command_for_line(&line) {
51 Some(command) => {
52 scope.run_command(&command, &line.args, &mut self.writer)
53 }
54 None => scope.default(&line),
55 };
56
57 let result = if let Ok(Action::SubScope(mut sub_scope)) = result {
58 self.run_scope(sub_scope.as_mut())
59 } else {
60 result
61 };
62
63 scope.after_command(&line, result)
64 }
65 }
66 }
67 };
68
69 if let Err(error) = last_result {
70 last_result = scope.handle_error_internal(error)
71 }
72 }
73
74 scope.after_loop();
75
76 match last_result {
77 Ok(Action::Exit) => Ok(Action::Done),
78 _ => last_result,
79 }
80 }
81}