aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel <kingdread@gmx.de>2020-04-21 14:23:50 +0200
committerDaniel <kingdread@gmx.de>2020-04-21 14:23:50 +0200
commit0a27adbc0bf3bbbf87fea9e55c00c38f61d55058 (patch)
treeb93fa88f0097c49fd7cc89bae257dfb63724bb56 /src
parent0ad7a333dc2b45f0ba658ea455284d086294a088 (diff)
downloadraidgrep-0a27adbc0bf3bbbf87fea9e55c00c38f61d55058.tar.gz
raidgrep-0a27adbc0bf3bbbf87fea9e55c00c38f61d55058.tar.bz2
raidgrep-0a27adbc0bf3bbbf87fea9e55c00c38f61d55058.zip
add a small repl
Diffstat (limited to 'src')
-rw-r--r--src/fexpr/mod.rs6
-rw-r--r--src/main.rs40
2 files changed, 33 insertions, 13 deletions
diff --git a/src/fexpr/mod.rs b/src/fexpr/mod.rs
index 5754d94..5610aba 100644
--- a/src/fexpr/mod.rs
+++ b/src/fexpr/mod.rs
@@ -46,9 +46,9 @@ pub enum FErrorKind {
}
/// Shortcut to create a new parser and parse the given input.
-pub fn parse_logfilter(
- input: &str,
-) -> Result<Box<dyn filters::log::LogFilter>, ParseError<usize, Token, FError>> {
+pub fn parse_logfilter<'a>(
+ input: &'a str,
+) -> Result<Box<dyn filters::log::LogFilter>, ParseError<usize, Token<'a>, FError>> {
grammar::LogFilterParser::new().parse(input)
}
diff --git a/src/main.rs b/src/main.rs
index 2e0c82f..ff882e5 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -2,7 +2,7 @@
use std::collections::HashMap;
use std::fmt;
use std::fs::File;
-use std::io::{BufReader, Read, Seek};
+use std::io::{BufReader, Read, Seek, Write};
use std::path::PathBuf;
use std::str::FromStr;
@@ -58,6 +58,10 @@ pub struct Opt {
#[structopt(long = "guilds")]
guilds: bool,
+ /// Run the REPL.
+ #[structopt(long)]
+ repl: bool,
+
/// The filter expression.
expression: Vec<String>,
}
@@ -211,9 +215,13 @@ fn run() -> Result<()> {
guilds::prepare_cache();
}
- let filter = build_filter(&opt)?;
-
- grep(&opt, &*filter)?;
+ if !opt.repl {
+ let expr_string = opt.expression.join(" ");
+ let filter = build_filter(&expr_string)?;
+ grep(&opt, &*filter)?;
+ } else {
+ repl(&opt)?;
+ }
if opt.guilds {
guilds::save_cache();
@@ -222,6 +230,22 @@ fn run() -> Result<()> {
Ok(())
}
+fn repl(opt: &Opt) -> Result<()> {
+ let stdin = std::io::stdin();
+ loop {
+ print!("Query> ");
+ std::io::stdout().flush()?;
+ let mut line = String::new();
+ stdin.read_line(&mut line)?;
+ let line = line.trim();
+ let parsed = build_filter(&line);
+ match parsed {
+ Ok(filter) => grep(&opt, &*filter)?,
+ Err(err) => display_error(&err.into()),
+ }
+ }
+}
+
/// Check if the given entry represents a log file, based on the file name.
fn is_log_file(entry: &DirEntry) -> bool {
entry
@@ -231,12 +255,8 @@ fn is_log_file(entry: &DirEntry) -> bool {
.unwrap_or(false)
}
-fn build_filter(opt: &Opt) -> Result<Box<dyn LogFilter>> {
- // Our error needs access to the string, so we make our lives easier by just leaking it into a
- // 'static lifetime. Otherwise we'd need to build this string in main() and pass it in.
- // We're fine with the small memory leak, as we're only dealing with a small string in a
- // short-lived program.
- let expr_string = Box::leak(Box::new(opt.expression.join(" ")));
+/// Small wrapper around `fexpr::parse_logfilter` to convert the returned `Err` to be `'static'.
+fn build_filter(expr_string: &str) -> Result<Box<dyn LogFilter>> {
if expr_string.trim().is_empty() {
return Err(anyhow!("Expected a filter to be given"));
}