From 0ed0ad1fd26cccb9f41379e2f0f2c77fca43c608 Mon Sep 17 00:00:00 2001 From: sigoden Date: Sun, 12 Mar 2023 07:54:18 +0800 Subject: chore: optimize readline multiline --- src/repl/validator.rs | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/repl/validator.rs (limited to 'src/repl/validator.rs') diff --git a/src/repl/validator.rs b/src/repl/validator.rs new file mode 100644 index 0000000..e1f6e99 --- /dev/null +++ b/src/repl/validator.rs @@ -0,0 +1,59 @@ +use reedline::{ValidationResult, Validator}; + +/// A default validator which checks for mismatched quotes and brackets +pub struct ReplValidator; + +impl Validator for ReplValidator { + fn validate(&self, line: &str) -> ValidationResult { + if incomplete_brackets(line) { + ValidationResult::Incomplete + } else { + ValidationResult::Complete + } + } +} + +fn incomplete_brackets(line: &str) -> bool { + let mut balance: Vec = Vec::new(); + let mut symbol = None; + for c in line.chars() { + match symbol { + Some(s) => match (s, c) { + ('{', '}') | ('(', ')') => { + balance.pop(); + } + _ if s == c => { + balance.push(c); + } + _ => {} + }, + None => match c { + '{' | '(' => { + balance.push(c); + symbol = Some(c) + } + _ => {} + }, + } + } + + !balance.is_empty() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_incomplete_brackets() { + assert!(incomplete_brackets("{")); + assert!(incomplete_brackets("(")); + assert!(!incomplete_brackets("{}")); + assert!(!incomplete_brackets("()")); + assert!(!incomplete_brackets("{ab\nc}")); + assert!(!incomplete_brackets("(ab\nc)")); + assert!(!incomplete_brackets("{[}")); + assert!(!incomplete_brackets("{{{{{}}}}}")); + assert!(incomplete_brackets("{{}")); + } +} -- cgit v1.2.3