blob: 80645df83945e95379189204001732063b8c1804 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
#![forbid(unsafe_code)]
use crate::commands::{ Command, CommandMap, Mode };
use crate::error::*;
use std::io::Write;
mod commands;
mod error;
struct TopLevelMode {
command_map: Box<CommandMap<TopLevelMode>>,
}
impl TopLevelMode {
fn new() -> Result<Self> {
let mut command_map = Box::new(CommandMap::new());
command_map.insert(Command::new("help", |mode, _params| {
println!("help Print this message.");
println!("quit Exit the program.");
Ok(Some(mode))
}))?;
command_map.insert(Command::new("quit", |_mode, _params| {
Ok(None)
}))?;
Ok(TopLevelMode { command_map })
}
}
impl Mode for TopLevelMode {
fn prompt_text(&self) -> Result<&str> {
Ok("secrets>")
}
fn dispatch(self: Box<Self>, params: &[&str])
-> Result<Option<Box<dyn Mode>>>
{
if params.len() > 0 {
if let Some(command) = self.command_map.get(params[0]) {
(command.implementation)(self, ¶ms[1..])
} else {
println!("No command named {}. Type help if you need help.",
params[0]);
Ok(Some(self))
}
} else {
default_empty_command()?;
Ok(Some(self))
}
}
}
fn default_empty_command() -> Result<()> {
println!("No command? Type help if you need help.");
Ok(())
}
fn main() -> Result<()> {
help();
let mut current_mode: Option<Box<dyn Mode>>
= Some(Box::new(TopLevelMode::new()?));
while let Some(mode) = current_mode {
if let Some(input) = prompt(mode.prompt_text()?)? {
let words: Vec<&str> = input.split_whitespace().collect();
current_mode = mode.dispatch(&words[..])?;
} else {
current_mode = None;
}
}
Ok(())
}
fn help() {
println!("Type a command (there are none yet)");
}
fn prompt(raw: &str) -> Result<Option<String>> {
let mut stdout = std::io::stdout();
stdout.write_all(format!("\n{} ", raw).as_bytes())?;
stdout.flush()?;
Ok(std::io::stdin().lines().next().transpose()?)
}
|