Implement parsing of inline tables
This commit is contained in:
parent
0042025904
commit
95085dba9a
|
@ -257,8 +257,7 @@ impl<'a> Parser<'a> {
|
||||||
Some(s) => s,
|
Some(s) => s,
|
||||||
None => return false
|
None => return false
|
||||||
};
|
};
|
||||||
self.ws();
|
if !self.keyval_sep() { return false }
|
||||||
if !self.expect('=') { return false }
|
|
||||||
let value = match self.value() {
|
let value = match self.value() {
|
||||||
Some(value) => value,
|
Some(value) => value,
|
||||||
None => return false,
|
None => return false,
|
||||||
|
@ -271,6 +270,13 @@ impl<'a> Parser<'a> {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn keyval_sep(&mut self) -> bool {
|
||||||
|
self.ws();
|
||||||
|
if !self.expect('=') { return false }
|
||||||
|
self.ws();
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
// Parses a value
|
// Parses a value
|
||||||
fn value(&mut self) -> Option<Value> {
|
fn value(&mut self) -> Option<Value> {
|
||||||
self.ws();
|
self.ws();
|
||||||
|
@ -280,6 +286,7 @@ impl<'a> Parser<'a> {
|
||||||
Some((pos, 't')) |
|
Some((pos, 't')) |
|
||||||
Some((pos, 'f')) => self.boolean(pos),
|
Some((pos, 'f')) => self.boolean(pos),
|
||||||
Some((pos, '[')) => self.array(pos),
|
Some((pos, '[')) => self.array(pos),
|
||||||
|
Some((pos, '{')) => self.inline_table(pos),
|
||||||
Some((pos, '-')) |
|
Some((pos, '-')) |
|
||||||
Some((pos, '+')) => self.number_or_datetime(pos),
|
Some((pos, '+')) => self.number_or_datetime(pos),
|
||||||
Some((pos, ch)) if is_digit(ch) => 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))
|
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,
|
fn insert(&mut self, into: &mut TomlTable, key: String, value: Value,
|
||||||
key_lo: usize) {
|
key_lo: usize) {
|
||||||
if into.contains_key(&key) {
|
if into.contains_key(&key) {
|
||||||
|
@ -1149,4 +1176,21 @@ trimmed in raw strings.
|
||||||
fn invalid_bare_numeral() {
|
fn invalid_bare_numeral() {
|
||||||
assert!(Parser::new("4").parse().is_none());
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue