From 46b790b5828c8367af6ec247937cfd86dcc79e8c Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Mon, 8 Aug 2022 13:47:38 +0100 Subject: [PATCH] option_parser: Simplify code for splitting on commas The parsing is now O(1) as we only consider each character in the input once and further it removes the need for allocating memory for reassembling the option parameter. Signed-off-by: Rob Bradford --- option_parser/src/lib.rs | 46 +++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/option_parser/src/lib.rs b/option_parser/src/lib.rs index 0653d2dec..7a3991242 100644 --- a/option_parser/src/lib.rs +++ b/option_parser/src/lib.rs @@ -40,26 +40,38 @@ type OptionParserResult = std::result::Result; fn split_commas_outside_brackets(s: &str) -> OptionParserResult> { let mut list: Vec = Vec::new(); - let mut opened_brackets: usize = 0; - for element in s.trim().split(',') { - if opened_brackets > 0 { - if let Some(last) = list.last_mut() { - *last = format!("{},{}", last, element); - } else { - return Err(OptionParserError::InvalidSyntax(s.to_owned())); - } - } else { - list.push(element.to_string()); - } + let mut opened_brackets = 0; + let mut current = String::new(); - opened_brackets += element.matches('[').count(); - let closing_brackets = element.matches(']').count(); - if closing_brackets > opened_brackets { - return Err(OptionParserError::InvalidSyntax(s.to_owned())); - } else { - opened_brackets -= closing_brackets; + for c in s.trim().chars() { + match c { + '[' => { + opened_brackets += 1; + current.push('['); + } + ']' => { + opened_brackets -= 1; + if opened_brackets < 0 { + return Err(OptionParserError::InvalidSyntax(s.to_owned())); + } + current.push(']'); + } + ',' => { + if opened_brackets > 0 { + current.push(',') + } else { + list.push(current); + current = String::new(); + } + } + c => current.push(c), } } + list.push(current); + + if opened_brackets != 0 { + return Err(OptionParserError::InvalidSyntax(s.to_owned())); + } Ok(list) }