From c0c112985b531bbcf503a2b1a8c2764030a16c99 Mon Sep 17 00:00:00 2001 From: mo8it Date: Sun, 24 Mar 2024 19:18:19 +0100 Subject: [PATCH] Replace regex with winnow --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/exercise.rs | 44 ++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3950c47..e42b8f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -533,10 +533,10 @@ dependencies = [ "indicatif", "notify-debouncer-mini", "predicates", - "regex", "serde", "serde_json", "toml", + "winnow", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 218b799..dd4c0c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,10 +15,10 @@ glob = "0.3.0" home = "0.5.9" indicatif = "0.17.8" notify-debouncer-mini = "0.4.1" -regex = "1.10.3" serde_json = "1.0.114" serde = { version = "1.0.197", features = ["derive"] } toml = "0.8.10" +winnow = "0.6.5" [[bin]] name = "rustlings" diff --git a/src/exercise.rs b/src/exercise.rs index b112fe8..8f580d3 100644 --- a/src/exercise.rs +++ b/src/exercise.rs @@ -1,4 +1,3 @@ -use regex::Regex; use serde::Deserialize; use std::fmt::{self, Display, Formatter}; use std::fs::{self, remove_file, File}; @@ -6,14 +5,34 @@ use std::io::{self, BufRead, BufReader}; use std::path::PathBuf; use std::process::{self, Command}; use std::{array, env, mem}; +use winnow::ascii::{space0, space1}; +use winnow::combinator::opt; +use winnow::Parser; const RUSTC_COLOR_ARGS: &[&str] = &["--color", "always"]; const RUSTC_EDITION_ARGS: &[&str] = &["--edition", "2021"]; const RUSTC_NO_DEBUG_ARGS: &[&str] = &["-C", "strip=debuginfo"]; -const I_AM_DONE_REGEX: &str = r"^\s*///?\s*I\s+AM\s+NOT\s+DONE"; const CONTEXT: usize = 2; const CLIPPY_CARGO_TOML_PATH: &str = "./exercises/22_clippy/Cargo.toml"; +fn not_done(input: &str) -> bool { + ( + space0::<_, ()>, + "//", + opt('/'), + space0, + 'I', + space1, + "AM", + space1, + "NOT", + space1, + "DONE", + ) + .parse_next(&mut &*input) + .is_ok() +} + // Get a temporary file name that is hopefully unique #[inline] fn temp_file() -> String { @@ -223,7 +242,6 @@ path = "{}.rs""#, Ok(n) }; - let re = Regex::new(I_AM_DONE_REGEX).unwrap(); let mut matched_line_ind: usize = 0; let mut prev_lines: [_; CONTEXT] = array::from_fn(|_| String::with_capacity(256)); let mut line = String::with_capacity(256); @@ -232,7 +250,7 @@ path = "{}.rs""#, match read_line(&mut line) { Ok(0) => break, Ok(_) => { - if re.is_match(&line) { + if not_done(&line) { let mut context = Vec::with_capacity(2 * CONTEXT + 1); for (ind, prev_line) in prev_lines .into_iter() @@ -413,4 +431,22 @@ mod test { let out = exercise.compile().unwrap().run().unwrap(); assert!(out.stdout.contains("THIS TEST TOO SHALL PASS")); } + + #[test] + fn test_not_done() { + assert!(not_done("// I AM NOT DONE")); + assert!(not_done("/// I AM NOT DONE")); + assert!(not_done("// I AM NOT DONE")); + assert!(not_done("/// I AM NOT DONE")); + assert!(not_done("// I AM NOT DONE")); + assert!(not_done("// I AM NOT DONE")); + assert!(not_done("// I AM NOT DONE")); + assert!(not_done("// I AM NOT DONE ")); + assert!(not_done("// I AM NOT DONE!")); + + assert!(!not_done("I AM NOT DONE")); + assert!(!not_done("// NOT DONE")); + assert!(!not_done("DONE")); + assert!(!not_done("// i am not done")); + } }