From 596763cfe9e62421d838ed2191c9163e5f5f2a15 Mon Sep 17 00:00:00 2001 From: "A. Taha Baki" Date: Thu, 20 Jul 2023 14:58:51 +0300 Subject: [PATCH 1/3] tests: update test for feature empty collection item. --- src/parser.rs | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/src/parser.rs b/src/parser.rs index 59bf2af..86b550e 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -456,6 +456,132 @@ mod tests { use super::*; use crate::tokenizer::Token; + #[test] + fn test_feature_empty_collection_item_at_the_end() { + assert_eq!( + parse(&vec![ + Token::Text("A".into(), 0), + Token::OBra(1), + Token::Text("B".into(), 2), + Token::Comma(3), + Token::Text("C".into(), 4), + Token::Comma(5), + Token::CBra(6), + ]), + Ok(Node::BraceExpansion { + prefix: Some(Box::new(Node::Text { + message: "A".into(), + start: 0 + })), + inside: Some(Box::new(Node::Collection { + items: vec![ + Node::Text { + message: "B".into(), + start: 2 + }, + Node::Text { + message: "C".into(), + start: 4 + }, + Node::Text { + message: String::new(), + start: 5 + }, + ], + start: 1, + end: 6 + })), + postfix: None, + start: 0, + end: 6 + }) + ) + } + + #[test] + fn test_feature_empty_collection_item_at_the_start() { + assert_eq!( + parse(&vec![ + Token::Text("A".into(), 0), + Token::OBra(1), + Token::Comma(2), + Token::Text("B".into(), 3), + Token::Comma(4), + Token::Text("C".into(), 5), + Token::CBra(6), + ]), + Ok(Node::BraceExpansion { + prefix: Some(Box::new(Node::Text { + message: "A".into(), + start: 0 + })), + inside: Some(Box::new(Node::Collection { + items: vec![ + Node::Text { + message: String::new(), + start: 2 + }, + Node::Text { + message: "B".into(), + start: 3 + }, + Node::Text { + message: "C".into(), + start: 5 + }, + ], + start: 1, + end: 6 + })), + postfix: None, + start: 0, + end: 6 + }) + ) + } + + #[test] + fn test_feature_empty_collection_item_in_the_middle() { + assert_eq!( + parse(&vec![ + Token::Text("A".into(), 0), + Token::OBra(1), + Token::Text("B".into(), 2), + Token::Comma(3), + Token::Comma(4), + Token::Text("C".into(), 5), + Token::CBra(6), + ]), + Ok(Node::BraceExpansion { + prefix: Some(Box::new(Node::Text { + message: "A".into(), + start: 0 + })), + inside: Some(Box::new(Node::Collection { + items: vec![ + Node::Text { + message: "B".into(), + start: 2 + }, + Node::Text { + message: String::new(), + start: 3 + }, + Node::Text { + message: "C".into(), + start: 5 + }, + ], + start: 1, + end: 6 + })), + postfix: None, + start: 0, + end: 6 + }) + ) + } + #[test] fn test_really_complex() { assert_eq!( From c44a2751c25e99576b90d14e2c2af6384e5136f7 Mon Sep 17 00:00:00 2001 From: "A. Taha Baki" Date: Thu, 20 Jul 2023 15:01:34 +0300 Subject: [PATCH 2/3] doc: update InvalidCommaUsage for the new feature --- src/parser.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parser.rs b/src/parser.rs index 86b550e..056b8c5 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -69,7 +69,7 @@ pub enum ParsingError { RangeEndLimitExpected(usize), /// It is not Text, but expected to be a text. ExpectedText(usize), - /// Comma is used invalid, e.g. `{,A,B}` or `{A,}` or `{,}` + /// Comma is used invalid, e.g. `{A..,B}` or `{A,..B}` InvalidCommaUsage(usize), /// Extra Closing Brace, e.g. `{} }` ExtraCBra(usize), From 7fd38afd79eb4633bdf5a4effa5ae042811db3fd Mon Sep 17 00:00:00 2001 From: "A. Taha Baki" Date: Thu, 20 Jul 2023 16:04:59 +0300 Subject: [PATCH 3/3] add: feature-empty-collection-item --- src/parser.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 056b8c5..418c5bd 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -370,15 +370,24 @@ fn collection(tokens: &Vec) -> Result { // start and end positions. let mut pos = (0_usize, 0_usize); // in the seperate function, we're dealing with `{}}` or `{{}`, no need to deal with it here. - let mut count = (0, 0); + // count of OBra (`{`), CBra (`}`), and the seperator (`,`). + let mut count = (0_usize, 0_usize, 0_usize); let mut collections: Vec> = vec![]; let mut current = vec![]; for token in tokens { match token { Token::Comma(s) if count.0 == (count.1 + 1) => { + // increase the seperator count by 1. + count.2 += 1; if current.is_empty() { - return Err(ParsingError::InvalidCommaUsage(*s)); + match collections.len() == 0 { + true => current.push(Token::Text(String::new(), s.clone())), + // The previous token was comma. + false => current.push(Token::Text(String::new(), s - 1)), + } } + // we dealt with if it's empty. + // so it can't be empty. collections.push(current.clone()); current.clear(); } @@ -404,9 +413,10 @@ fn collection(tokens: &Vec) -> Result { _ => current.push(token.clone()), } } - if !current.is_empty() { - collections.push(current); + if current.is_empty() && collections.len() == count.2 { + current.push(Token::Text(String::new(), pos.1 - 1)); } + collections.push(current); match collections.len() { 0 => Err(ParsingError::NothingInBraces(pos.0)), 1 => {