Convert tools/cli to failure.

This commit is contained in:
Grisha Kruglov 2018-06-04 20:59:27 -04:00 committed by Nick Alexander
parent 800f404a23
commit 0adfa6aae6
5 changed files with 43 additions and 19 deletions

View file

@ -20,6 +20,8 @@ test = false
[dependencies] [dependencies]
combine = "2.2.2" combine = "2.2.2"
env_logger = "0.5" env_logger = "0.5"
failure = "0.1.1"
failure_derive = "0.1.1"
getopts = "0.2" getopts = "0.2"
lazy_static = "0.2" lazy_static = "0.2"
linefeed = "0.4" linefeed = "0.4"
@ -28,7 +30,6 @@ tabwriter = "1"
tempfile = "1.1" tempfile = "1.1"
termion = "1" termion = "1"
time = "0.1" time = "0.1"
error-chain = { git = "https://github.com/rnewman/error-chain", branch = "rnewman/sync" }
[dependencies.rusqlite] [dependencies.rusqlite]
version = "0.13" version = "0.13"

View file

@ -30,14 +30,26 @@ use combine::combinator::{
try, try,
}; };
use errors as cli; use CliError;
use edn; use edn;
use failure::{
Compat,
Error,
};
use mentat::{ use mentat::{
CacheDirection, CacheDirection,
}; };
#[macro_export]
macro_rules! bail {
($e:expr) => (
return Err($e.into());
)
}
pub static COMMAND_CACHE: &'static str = &"cache"; pub static COMMAND_CACHE: &'static str = &"cache";
pub static COMMAND_CLOSE: &'static str = &"close"; pub static COMMAND_CLOSE: &'static str = &"close";
pub static COMMAND_EXIT_LONG: &'static str = &"exit"; pub static COMMAND_EXIT_LONG: &'static str = &"exit";
@ -188,7 +200,7 @@ impl Command {
} }
} }
pub fn command(s: &str) -> Result<Command, cli::Error> { pub fn command(s: &str) -> Result<Command, Error> {
let path = || many1::<String, _>(satisfy(|c: char| !c.is_whitespace())); let path = || many1::<String, _>(satisfy(|c: char| !c.is_whitespace()));
let argument = || many1::<String, _>(satisfy(|c: char| !c.is_whitespace())); let argument = || many1::<String, _>(satisfy(|c: char| !c.is_whitespace()));
let arguments = || sep_end_by::<Vec<_>, _, _>(many1(satisfy(|c: char| !c.is_whitespace())), many1::<Vec<_>, _>(space())).expected("arguments"); let arguments = || sep_end_by::<Vec<_>, _, _>(many1(satisfy(|c: char| !c.is_whitespace())), many1::<Vec<_>, _>(space())).expected("arguments");
@ -202,7 +214,7 @@ pub fn command(s: &str) -> Result<Command, cli::Error> {
let edn_arg_parser = || spaces() let edn_arg_parser = || spaces()
.with(look_ahead(string("[").or(string("{"))) .with(look_ahead(string("[").or(string("{")))
.with(many1::<Vec<_>, _>(try(any()))) .with(many1::<Vec<_>, _>(try(any())))
.and_then(|args| -> Result<String, cli::Error> { .and_then(|args| -> Result<String, Compat<Error>> {
Ok(args.iter().collect()) Ok(args.iter().collect())
}) })
); );
@ -217,10 +229,10 @@ pub fn command(s: &str) -> Result<Command, cli::Error> {
.with(arguments()) .with(arguments())
.map(move |args| { .map(move |args| {
if args.len() < num_args { if args.len() < num_args {
bail!(cli::ErrorKind::CommandParse("Missing required argument".to_string())); bail!(CliError::CommandParse("Missing required argument".to_string()));
} }
if args.len() > num_args { if args.len() > num_args {
bail!(cli::ErrorKind::CommandParse(format!("Unrecognized argument {:?}", args[num_args]))); bail!(CliError::CommandParse(format!("Unrecognized argument {:?}", args[num_args])));
} }
Ok(args) Ok(args)
}) })
@ -239,7 +251,7 @@ pub fn command(s: &str) -> Result<Command, cli::Error> {
.with(no_arg_parser()) .with(no_arg_parser())
.map(|args| { .map(|args| {
if !args.is_empty() { if !args.is_empty() {
bail!(cli::ErrorKind::CommandParse(format!("Unrecognized argument {:?}", args[0])) ); bail!(CliError::CommandParse(format!("Unrecognized argument {:?}", args[0])) );
} }
Ok(Command::Close) Ok(Command::Close)
}); });
@ -248,7 +260,7 @@ pub fn command(s: &str) -> Result<Command, cli::Error> {
.with(no_arg_parser()) .with(no_arg_parser())
.map(|args| { .map(|args| {
if !args.is_empty() { if !args.is_empty() {
bail!(cli::ErrorKind::CommandParse(format!("Unrecognized argument {:?}", args[0])) ); bail!(CliError::CommandParse(format!("Unrecognized argument {:?}", args[0])) );
} }
Ok(Command::Exit) Ok(Command::Exit)
}); });
@ -302,7 +314,7 @@ pub fn command(s: &str) -> Result<Command, cli::Error> {
.with(no_arg_parser()) .with(no_arg_parser())
.map(|args| { .map(|args| {
if !args.is_empty() { if !args.is_empty() {
bail!(cli::ErrorKind::CommandParse(format!("Unrecognized argument {:?}", args[0])) ); bail!(CliError::CommandParse(format!("Unrecognized argument {:?}", args[0])) );
} }
Ok(Command::Schema) Ok(Command::Schema)
}); });
@ -312,10 +324,10 @@ pub fn command(s: &str) -> Result<Command, cli::Error> {
.with(arguments()) .with(arguments())
.map(|args| { .map(|args| {
if args.len() < 1 { if args.len() < 1 {
bail!(cli::ErrorKind::CommandParse("Missing required argument".to_string())); bail!(CliError::CommandParse("Missing required argument".to_string()));
} }
if args.len() > 2 { if args.len() > 2 {
bail!(cli::ErrorKind::CommandParse(format!("Unrecognized argument {:?}", args[2]))); bail!(CliError::CommandParse(format!("Unrecognized argument {:?}", args[2])));
} }
Ok(Command::Sync(args.clone())) Ok(Command::Sync(args.clone()))
}); });
@ -335,7 +347,7 @@ pub fn command(s: &str) -> Result<Command, cli::Error> {
spaces() spaces()
.skip(token('.')) .skip(token('.'))
.with(choice::<[&mut Parser<Input = _, Output = Result<Command, cli::Error>>; 16], _> .with(choice::<[&mut Parser<Input = _, Output = Result<Command, Error>>; 16], _>
([&mut try(help_parser), ([&mut try(help_parser),
&mut try(import_parser), &mut try(import_parser),
&mut try(timer_parser), &mut try(timer_parser),
@ -353,7 +365,7 @@ pub fn command(s: &str) -> Result<Command, cli::Error> {
&mut try(sync_parser), &mut try(sync_parser),
&mut try(transact_parser)])) &mut try(transact_parser)]))
.parse(s) .parse(s)
.unwrap_or((Err(cli::ErrorKind::CommandParse(format!("Invalid command {:?}", s)).into()), "")).0 .unwrap_or((Err(CliError::CommandParse(format!("Invalid command {:?}", s)).into()), "")).0
} }
#[cfg(test)] #[cfg(test)]

View file

@ -28,7 +28,7 @@ use command_parser::{
command, command,
}; };
use errors as cli; use failure::Error;
/// Starting prompt /// Starting prompt
const DEFAULT_PROMPT: &'static str = "mentat=> "; const DEFAULT_PROMPT: &'static str = "mentat=> ";
@ -97,7 +97,7 @@ impl InputReader {
/// Reads a single command, item, or statement from `stdin`. /// Reads a single command, item, or statement from `stdin`.
/// Returns `More` if further input is required for a complete result. /// Returns `More` if further input is required for a complete result.
/// In this case, the input received so far is buffered internally. /// In this case, the input received so far is buffered internally.
pub fn read_input(&mut self) -> Result<InputResult, cli::Error> { pub fn read_input(&mut self) -> Result<InputResult, Error> {
let prompt = if self.in_process_cmd.is_some() { MORE_PROMPT } else { DEFAULT_PROMPT }; let prompt = if self.in_process_cmd.is_some() { MORE_PROMPT } else { DEFAULT_PROMPT };
let prompt = format!("{blue}{prompt}{reset}", let prompt = format!("{blue}{prompt}{reset}",
blue = color::Fg(::BLUE), blue = color::Fg(::BLUE),

View file

@ -10,12 +10,13 @@
#![crate_name = "mentat_cli"] #![crate_name = "mentat_cli"]
#[macro_use] extern crate failure_derive;
#[macro_use] extern crate log; #[macro_use] extern crate log;
#[macro_use] extern crate lazy_static; #[macro_use] extern crate lazy_static;
#[macro_use] extern crate error_chain;
extern crate combine; extern crate combine;
extern crate env_logger; extern crate env_logger;
extern crate failure;
extern crate getopts; extern crate getopts;
extern crate linefeed; extern crate linefeed;
extern crate rusqlite; extern crate rusqlite;
@ -41,7 +42,12 @@ static GREEN: color::Rgb = color::Rgb(0x77, 0xFF, 0x99);
pub mod command_parser; pub mod command_parser;
pub mod input; pub mod input;
pub mod repl; pub mod repl;
pub mod errors;
#[derive(Debug, Fail)]
pub enum CliError {
#[fail(display = "{}", _0)]
CommandParse(String),
}
pub fn run() -> i32 { pub fn run() -> i32 {
env_logger::init(); env_logger::init();

View file

@ -11,6 +11,11 @@
use std::io::Write; use std::io::Write;
use std::process; use std::process;
use failure::{
err_msg,
Error,
};
use tabwriter::TabWriter; use tabwriter::TabWriter;
use termion::{ use termion::{
@ -383,7 +388,7 @@ impl Repl {
if self.path.is_empty() || path != self.path { if self.path.is_empty() || path != self.path {
let next = match encryption_key { let next = match encryption_key {
#[cfg(not(feature = "sqlcipher"))] #[cfg(not(feature = "sqlcipher"))]
Some(_) => bail!(".open_encrypted and .empty_encrypted require the sqlcipher Mentat feature"), Some(_) => return Err(err_msg(".open_encrypted and .empty_encrypted require the sqlcipher Mentat feature")),
#[cfg(feature = "sqlcipher")] #[cfg(feature = "sqlcipher")]
Some(k) => { Some(k) => {
if empty { if empty {
@ -467,7 +472,7 @@ impl Repl {
output.flush().unwrap(); output.flush().unwrap();
} }
fn print_results(&self, query_output: QueryOutput) -> Result<(), ::errors::Error> { fn print_results(&self, query_output: QueryOutput) -> Result<(), Error> {
let stdout = ::std::io::stdout(); let stdout = ::std::io::stdout();
let mut output = TabWriter::new(stdout.lock()); let mut output = TabWriter::new(stdout.lock());