diff options
Diffstat (limited to 'src/cli/cmd/mod.rs')
| -rw-r--r-- | src/cli/cmd/mod.rs | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/cli/cmd/mod.rs b/src/cli/cmd/mod.rs new file mode 100644 index 0000000..29063e8 --- /dev/null +++ b/src/cli/cmd/mod.rs @@ -0,0 +1,53 @@ +//! The commands that can be performed in the CLI + +pub mod save; + +pub use save::*; + +use crate::Editor; +use std::ops::RangeInclusive; + +/// Errors that can occur when parsing a command. This is for syntax checking, the +/// semantics are checked when trying to execute the command. +#[allow(missing_docs)] +#[derive(thiserror::Error, Debug)] +pub enum CmdParseError { + #[error("no command specified")] + StringEmpty, + #[error("the command {0} is unknown")] + NoSuchCmd(String), + #[error("wrong number of arguments. Expected in range {1:?}, but received {0}")] + WrongNumberOfArgs(usize, RangeInclusive<usize>), + #[error("{0} cannot be converted into a {1}, which is required")] + InvalidArgType(String, &'static str), +} + +/// Attempts to parse a command from the given string. If it is unsuccessful, it returns a +/// [CmdParseError]. +pub fn parse_command(string: &str) -> Result<Box<dyn Command>, CmdParseError> { + if string.is_empty() { + return Err(CmdParseError::StringEmpty); + } + + let parts: Vec<&str> = string.split_whitespace().collect(); + match parts[0] { + "w" => Ok(Box::new(Save::from_args(&parts[1..])?)), + other => Err(CmdParseError::NoSuchCmd(other.to_owned())), + } +} + +/// Indicates that this entity (command) can be created from arguments. Make sure to check what is +/// expected, to pass the arguments to the correct command. +pub trait FromArgs: Sized { + /// Creates a new instance from the arguments provided. If for whatever reason the syntax of the + /// given arguments is correct an [ArgParseError] is returned. + fn from_args(args: &[&str]) -> Result<Self, CmdParseError>; +} + +/// A common trait for all commands. +pub trait Command { + /// Process this command on the provided context. Returns either a string with the output of the + /// command when everything went right with it, or an error string explaining what went wrong, + /// which can be displayed to the user. + fn process(&self, editor: &mut Editor) -> Result<String, String>; +} |
