From 3a1bf5cf1cdd06cee4616abefafd44096dacf70f Mon Sep 17 00:00:00 2001 From: technetos Date: Thu, 17 Jun 2021 19:49:41 -0400 Subject: [PATCH 1/2] add support for quoted values in key value optionals --- src/commands.rs | 63 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 15 deletions(-) diff --git a/src/commands.rs b/src/commands.rs index c022215..bbf7497 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -78,16 +78,22 @@ impl Commands { .filter(|segment| segment.len() > 0) .enumerate() .for_each(|(i, segment)| { - if let Some(name) = key_value_pair(segment) { + if let Some(kv_pair) = key_value_pair(segment) { if let Some(lambda) = opt_lambda_state { - state = self.add_key_value(name, lambda); + state = match kv_pair { + KeyValuePair::Quoted(name) => self.add_quoted_key_value(name, lambda), + KeyValuePair::Unquoted(name) => self.add_key_value(name, lambda), + }; self.state_machine.add_next_state(state, lambda); opt_final_states.push(state); } else { opt_final_states.push(state); state = self.add_space(state, i); opt_lambda_state = Some(state); - state = self.add_key_value(name, state); + state = match kv_pair { + KeyValuePair::Quoted(name) => self.add_quoted_key_value(name, state), + KeyValuePair::Unquoted(name) => self.add_key_value(name, state), + }; self.state_machine .add_next_state(state, opt_lambda_state.unwrap()); opt_final_states.push(state); @@ -330,18 +336,45 @@ impl Commands { state } + + fn add_quoted_key_value(&mut self, name: &'static str, mut state: usize) -> usize { + name.chars().for_each(|c| { + state = self.state_machine.add(state, CharacterSet::from_char(c)); + }); + state = self.state_machine.add(state, CharacterSet::from_char('=')); + state = self.state_machine.add(state, CharacterSet::from_char('"')); + + state = self.state_machine.add(state, CharacterSet::any()); + self.state_machine.add_next_state(state, state); + self.state_machine.start_parse(state, name); + self.state_machine.end_parse(state); + + state = self.state_machine.add(state, CharacterSet::from_char('"')); + + state + } +} + +enum KeyValuePair { + Quoted(&'static str), + Unquoted(&'static str), } -fn key_value_pair(s: &'static str) -> Option<&'static str> { - s.match_indices("={}") - .next() - .map(|pair| { - let name = &s[0..pair.0]; - if name.len() > 0 { - Some(name) - } else { - None - } - }) - .flatten() +fn key_value_pair(s: &'static str) -> Option { + let len = s.len(); + + if len <= 3 { + return None; + } + + let delim = &s[len - 3..]; + let key = &s[..len - 3]; + + if delim == "={}" { + Some(KeyValuePair::Unquoted(key)) + } else if delim == "=[]" { + Some(KeyValuePair::Quoted(key)) + } else { + None + } } From 5d3935f47bcbe58f19480cc8b1aa7ad61d809097 Mon Sep 17 00:00:00 2001 From: technetos Date: Fri, 18 Jun 2021 13:01:46 -0400 Subject: [PATCH 2/2] revert to just ={} and support both quoted and unquoted syntax on kv pairs --- src/commands.rs | 74 +++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 39 deletions(-) diff --git a/src/commands.rs b/src/commands.rs index bbf7497..a2fcf66 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -65,7 +65,7 @@ impl Commands { info!("Adding command {}", &command); let mut state = 0; - let mut opt_lambda_state = None; + let mut reused_space_state = None; let mut opt_final_states = vec![]; let handler = Arc::new(Command { @@ -78,28 +78,32 @@ impl Commands { .filter(|segment| segment.len() > 0) .enumerate() .for_each(|(i, segment)| { - if let Some(kv_pair) = key_value_pair(segment) { - if let Some(lambda) = opt_lambda_state { - state = match kv_pair { - KeyValuePair::Quoted(name) => self.add_quoted_key_value(name, lambda), - KeyValuePair::Unquoted(name) => self.add_key_value(name, lambda), - }; + if let Some(name) = key_value_pair(segment) { + if let Some(lambda) = reused_space_state { + state = self.add_key_value(name, lambda); + self.state_machine.add_next_state(state, lambda); + opt_final_states.push(state); + + state = self.add_quoted_key_value(name, lambda); self.state_machine.add_next_state(state, lambda); opt_final_states.push(state); } else { opt_final_states.push(state); state = self.add_space(state, i); - opt_lambda_state = Some(state); - state = match kv_pair { - KeyValuePair::Quoted(name) => self.add_quoted_key_value(name, state), - KeyValuePair::Unquoted(name) => self.add_key_value(name, state), - }; + reused_space_state = Some(state); + + state = self.add_key_value(name, state); self.state_machine - .add_next_state(state, opt_lambda_state.unwrap()); + .add_next_state(state, reused_space_state.unwrap()); + opt_final_states.push(state); + + state = self.add_quoted_key_value(name, reused_space_state.unwrap()); + self.state_machine + .add_next_state(state, reused_space_state.unwrap()); opt_final_states.push(state); } } else { - opt_lambda_state = None; + reused_space_state = None; opt_final_states.truncate(0); let last_state = state; state = self.add_space(state, i); @@ -128,7 +132,7 @@ impl Commands { } }); - if opt_lambda_state.is_some() { + if reused_space_state.is_some() { opt_final_states.iter().for_each(|state| { self.state_machine.set_final_state(*state); self.state_machine.set_handler(*state, handler.clone()); @@ -328,7 +332,7 @@ impl Commands { state = self.state_machine.add(state, CharacterSet::from_char('=')); let mut char_set = CharacterSet::any(); - char_set.remove(&[' ', '\n']); + char_set.remove(&[' ', '\n', '"']); state = self.state_machine.add(state, char_set); self.state_machine.add_next_state(state, state); self.state_machine.start_parse(state, name); @@ -344,7 +348,9 @@ impl Commands { state = self.state_machine.add(state, CharacterSet::from_char('=')); state = self.state_machine.add(state, CharacterSet::from_char('"')); - state = self.state_machine.add(state, CharacterSet::any()); + let mut char_set = CharacterSet::any(); + char_set.remove(&['"']); + state = self.state_machine.add(state, char_set); self.state_machine.add_next_state(state, state); self.state_machine.start_parse(state, name); self.state_machine.end_parse(state); @@ -355,26 +361,16 @@ impl Commands { } } -enum KeyValuePair { - Quoted(&'static str), - Unquoted(&'static str), -} - -fn key_value_pair(s: &'static str) -> Option { - let len = s.len(); - - if len <= 3 { - return None; - } - - let delim = &s[len - 3..]; - let key = &s[..len - 3]; - - if delim == "={}" { - Some(KeyValuePair::Unquoted(key)) - } else if delim == "=[]" { - Some(KeyValuePair::Quoted(key)) - } else { - None - } +fn key_value_pair(s: &'static str) -> Option<&'static str> { + s.match_indices("={}") + .next() + .map(|pair| { + let name = &s[0..pair.0]; + if name.len() > 0 { + Some(name) + } else { + None + } + }) + .flatten() }