diff --git a/src/lib.rs b/src/lib.rs index b2819a7..67c567f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1 +1 @@ -pub mod parser; \ No newline at end of file +pub mod parser; diff --git a/src/parser.rs b/src/parser.rs index c40a4d1..18620a3 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -3,6 +3,7 @@ use colorful::*; use rand::prelude::*; use std::fs::*; use std::iter::repeat_with; +const CONTROLS: [char; 3] = ['\n', '\r', '\t']; #[derive(Clone, Debug)] pub struct Parser { pub file: Option, @@ -25,7 +26,7 @@ impl Parser { } } pub fn next_token(&mut self) -> Option> { - if self.position == (self.context.len() - 1) { + if (self.position) >= (self.context.len() - 1) { return None; } let substr: &str = self @@ -45,8 +46,8 @@ impl Parser { .collect::>(), ) } - fn is_vailid_token(&self, token: &str) -> bool { - self.parse(vec![token]).is_ok() || token.parse::().is_ok() + pub fn is_vailid_token(&self, token: &str) -> bool { + self.parse(vec![token]).is_ok() || token.parse::().is_ok() || CONTROLS.iter().any(|&x| token.contains(x)) } pub fn parse(&self, tokens: Vec<&str>) -> Result { if tokens.len() != 1 { @@ -73,11 +74,15 @@ impl Parser { .collect::() }); } - "string" => Ok( - repeat_with(|| thread_rng().gen_range(10_u8..126_u8) as char) - .take(random::() as usize) - .collect::(), - ), + "string" => Ok(repeat_with(|| { + if random::() % 26 == 0 { + CONTROLS[thread_rng().gen_range(0..=2)] + } else { + thread_rng().gen_range(32_u8..=126_u8) as char + } + }) + .take(random::() as usize) + .collect::()), "char" => Ok(random::().to_string()), _ => bail!( "{}", @@ -105,19 +110,20 @@ impl Parser { ) .to_string()); } - _ => { - if !self.is_vailid_token(i) { - ret = Err(anyhow!( - "{}", - format!( - "failed to parse at position {} : read undeclared tokens", - self.position + 1 - ) - .color(Color::Red) - .bold() - )); + "contains" => { + if tokens[0] != "string" { + ret = Err(anyhow!("{}\n{}",format!("Parse error at position {} : unable to confine `contains` for current type",self.position + 1).color(Color::Red).bold(),"note : the multi token `contains` is only valid for type string".color(Color::Blue))); + } else { + let mut str = self.parse(vec!["string"]).unwrap(); + if !str.contains(tokens[c + 1]) { + str.insert_str(thread_rng().gen_range(0..str.len()), tokens[c + 1]); + } + ret = Ok(str); } } + _ => { + + } } } ret