From 85ba7c8152887c2be44349ad2fb01bff1c7046df Mon Sep 17 00:00:00 2001 From: ppom Date: Tue, 1 Oct 2024 12:00:00 +0200 Subject: [PATCH] implement test-regex --- rust/src/client/mod.rs | 90 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 85 insertions(+), 5 deletions(-) diff --git a/rust/src/client/mod.rs b/rust/src/client/mod.rs index 91aa1a1..4e6fe5a 100644 --- a/rust/src/client/mod.rs +++ b/rust/src/client/mod.rs @@ -1,10 +1,19 @@ -use std::{error::Error, io::stdout, os::unix::net::UnixStream, path::PathBuf, process::exit}; +use std::{ + collections::BTreeSet, + error::Error, + io::{stdin, stdout, BufRead, BufReader}, + os::unix::net::UnixStream, + path::PathBuf, + process::exit, + sync::Arc, +}; use bincode::Options; -use log::{debug, error, Level}; +use log::{error, info, Level}; +use regex::Regex; use crate::{ - concepts::{ClientRequest, ClientStatus, DaemonResponse, Order}, + concepts::{ClientRequest, ClientStatus, Config, DaemonResponse, Order, Pattern}, utils::{bincode_options, cli::Format, SimpleLogger}, }; macro_rules! or_quit { @@ -71,10 +80,81 @@ pub fn request( } } -pub fn test_regex(config_path: PathBuf, regex: String, line: Option) { +pub fn test_regex(config_path: PathBuf, mut regex: String, line: Option) { if let Err(err) = SimpleLogger::init(Level::Debug) { eprintln!("ERROR could not initialize logging: {err}"); exit(1); } - debug!("test-regex {:?} {:?} {:?} ", config_path, regex, line); + + let config: Config = match Config::from_file(&config_path) { + Ok(config) => config, + Err(err) => { + error!("{err}"); + exit(1); + } + }; + + // Code close to Filter::setup() + let mut used_patterns: BTreeSet> = BTreeSet::new(); + for pattern in config.patterns().values() { + if let Some(index) = regex.find(pattern.name_with_braces()) { + // we already `find` it, so we must be able to `rfind` it + #[allow(clippy::unwrap_used)] + if regex.rfind(pattern.name_with_braces()).unwrap() != index { + error!( + "pattern {} present multiple times in regex", + pattern.name_with_braces() + ); + exit(1); + } + used_patterns.insert(pattern.clone()); + } + regex = regex.replacen(pattern.name_with_braces(), &pattern.regex, 1); + } + + let compiled = match Regex::new(®ex) { + Ok(reg) => reg, + Err(err) => { + error!("regex doesn't compile: {err}"); + exit(1); + } + }; + + let match_closure = |line: String| { + let mut ignored = false; + if let Some(matches) = compiled.captures(&line) { + let mut result = Vec::new(); + if used_patterns.len() != 0 { + for pattern in used_patterns.iter() { + if let Some(match_) = matches.name(pattern.name()) { + result.push(match_.as_str().to_string()); + if !pattern.not_an_ignore(match_.as_str()) { + ignored = true; + } + } + } + if !ignored { + println!("\x1b[32mmatching\x1b[0m {result:?}: {line}"); + } else { + println!("\x1b[33mignore matching\x1b[0m {result:?}: {line}"); + } + } else { + println!("\x1b[32mmatching\x1b[0m: {line}"); + } + } else { + println!("\x1b[31mno match\x1b[0m: {line}"); + } + }; + + if let Some(line) = line { + match_closure(line); + } else { + info!("no second argument: reading from stdin"); + for line in BufReader::new(stdin()).lines() { + match line { + Ok(line) => match_closure(line), + Err(_) => break, + }; + } + } }