diff options
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 96 |
1 files changed, 94 insertions, 2 deletions
diff --git a/src/main.rs b/src/main.rs index c9de2c5..80645df 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,98 @@ #![forbid(unsafe_code)] +use crate::commands::{ Command, CommandMap, Mode }; +use crate::error::*; -fn main() { - println!("yay"); +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()?) } |