diff options
author | Alex Crichton <alex@alexcrichton.com> | 2015-02-07 22:01:13 -0800 |
---|---|---|
committer | Alex Crichton <alex@alexcrichton.com> | 2015-02-07 22:02:32 -0800 |
commit | 95085dba9a98a8e9ff2280945d6aede5e7de9fec (patch) | |
tree | 9648de6120d3c2330c2f84e67aa5440995f7f0aa | |
parent | 00420259044e9e961b9d8a80e5482ffc58250145 (diff) | |
download | milf-rs-95085dba9a98a8e9ff2280945d6aede5e7de9fec.tar.gz milf-rs-95085dba9a98a8e9ff2280945d6aede5e7de9fec.zip |
Implement parsing of inline tables
-rw-r--r-- | src/parser.rs | 48 |
1 files changed, 46 insertions, 2 deletions
diff --git a/src/parser.rs b/src/parser.rs index 723ac3a..13044e3 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -257,8 +257,7 @@ impl<'a> Parser<'a> { Some(s) => s, None => return false }; - self.ws(); - if !self.expect('=') { return false } + if !self.keyval_sep() { return false } let value = match self.value() { Some(value) => value, None => return false, @@ -271,6 +270,13 @@ impl<'a> Parser<'a> { return true } + fn keyval_sep(&mut self) -> bool { + self.ws(); + if !self.expect('=') { return false } + self.ws(); + true + } + // Parses a value fn value(&mut self) -> Option<Value> { self.ws(); @@ -280,6 +286,7 @@ impl<'a> Parser<'a> { Some((pos, 't')) | Some((pos, 'f')) => self.boolean(pos), Some((pos, '[')) => self.array(pos), + Some((pos, '{')) => self.inline_table(pos), Some((pos, '-')) | Some((pos, '+')) => self.number_or_datetime(pos), Some((pos, ch)) if is_digit(ch) => self.number_or_datetime(pos), @@ -667,6 +674,26 @@ impl<'a> Parser<'a> { return Some(Array(ret)) } + fn inline_table(&mut self, _start: usize) -> Option<Value> { + if !self.expect('{') { return None } + self.ws(); + let mut ret = BTreeMap::new(); + if self.eat('}') { return Some(Table(ret)) } + loop { + let lo = self.next_pos(); + let key = match self.key_name() { Some(s) => s, None => return None }; + if !self.keyval_sep() { return None } + let value = match self.value() { Some(v) => v, None => return None }; + self.insert(&mut ret, key, value, lo); + + self.ws(); + if self.eat('}') { break } + if !self.expect(',') { return None } + self.ws(); + } + return Some(Table(ret)) + } + fn insert(&mut self, into: &mut TomlTable, key: String, value: Value, key_lo: usize) { if into.contains_key(&key) { @@ -1149,4 +1176,21 @@ trimmed in raw strings. fn invalid_bare_numeral() { assert!(Parser::new("4").parse().is_none()); } + + #[test] + fn inline_tables() { + assert!(Parser::new("a = {}").parse().is_some()); + assert!(Parser::new("a = {b=1}").parse().is_some()); + assert!(Parser::new("a = { b = 1 }").parse().is_some()); + assert!(Parser::new("a = {a=1,b=2}").parse().is_some()); + assert!(Parser::new("a = {a=1,b=2,c={}}").parse().is_some()); + assert!(Parser::new("a = {a=1,}").parse().is_none()); + assert!(Parser::new("a = {,}").parse().is_none()); + assert!(Parser::new("a = {a=1,a=1}").parse().is_none()); + assert!(Parser::new("a = {\n}").parse().is_none()); + assert!(Parser::new("a = {").parse().is_none()); + assert!(Parser::new("a = {a=[\n]}").parse().is_some()); + assert!(Parser::new("a = {\"a\"=[\n]}").parse().is_some()); + assert!(Parser::new("a = [\n{},\n{},\n]").parse().is_some()); + } } |