Support for nested table arrays

This commit is contained in:
moandji.ezana 2014-04-07 14:38:34 +02:00
parent 095e33a03b
commit 453ce84fc5
4 changed files with 63 additions and 7 deletions

View file

@ -89,7 +89,7 @@ Long c = toml.getLong("c"); // returns null
### Table arrays
Table arrays are mapped to `List`s with `Toml#getTables(String)`. Custom classes are also supported.
Table arrays are mapped to `List`s with `Toml#getTables(String)`. Custom classes and nested table arrays are supported.
````
[[products]]

View file

@ -267,9 +267,11 @@ class TomlParser extends BaseParser<Object> {
return true;
}
for (String splitKey : split) {
for (int i = 0; i < split.length; i++) {
String splitKey = split[i];
if (!newTable.containsKey(splitKey)) {
if (array) {
if (array && isLast(split, i)) {
ArrayList<Map<String, Object>> newTableList = new ArrayList<Map<String, Object>>();
newTable.put(splitKey, newTableList);
} else {
@ -277,16 +279,21 @@ class TomlParser extends BaseParser<Object> {
}
}
Object currentValue = newTable.get(splitKey);
if ((array && !(currentValue instanceof List)) || (!array && !(currentValue instanceof Map))) {
if (!(currentValue instanceof List) && !(currentValue instanceof Map)) {
results().errors.append("Could not create table ").append(name).append(": key already has a value!\n");
return true;
}
if (currentValue instanceof List) {
Map<String, Object> newTableListItem = new HashMap<String,Object>();
currentValue = ((List<Map<String, Object>>) currentValue).add(newTableListItem);
currentValue = newTableListItem;
List<Map<String, Object>> currentList = (List<Map<String, Object>>) currentValue;
if (array && isLast(split, i)) {
Map<String, Object> newTableListItem = new HashMap<String,Object>();
currentList.add(newTableListItem);
currentValue = newTableListItem;
} else {
currentValue = currentList.get(currentList.size() - 1);
}
}
newTable = (Map<String, Object>) currentValue;
@ -311,6 +318,10 @@ class TomlParser extends BaseParser<Object> {
values.put(name, value);
}
private boolean isLast(String[] array, int index) {
return index == array.length - 1;
}
private TomlParser.Results results() {
return (Results) peek(getContext().getValueStack().size() - 1);
}

View file

@ -29,4 +29,31 @@ public class TableArrayTest {
assertEquals(284758393L, products.get(2).getLong("sku").longValue());
assertEquals("gray", products.get(2).getString("color"));
}
@Test
public void should_parse_nested_table_arrays() throws Exception {
Toml toml = new Toml().parse(new File(getClass().getResource("fruit_table_array.toml").getFile()));
List<Toml> fruits = toml.getTables("fruit");
assertEquals(2, fruits.size());
Toml apple = fruits.get(0);
assertEquals("apple", apple.getString("name"));
assertEquals("red", apple.getTable("physical").getString("color"));
assertEquals("round", apple.getTable("physical").getString("shape"));
assertEquals(2, apple.getTables("variety").size());
Toml banana = fruits.get(1);
assertEquals("banana", banana.getString("name"));
assertEquals(1, banana.getTables("variety").size());
assertEquals("plantain", banana.getTables("variety").get(0).getString("name"));
}
@Test
public void should_create_array_ancestors_as_tables() throws Exception {
Toml toml = new Toml().parse("[[a.b.c]]\n id=3");
assertEquals(3, toml.getTable("a").getTable("b").getTables("c").get(0).getLong("id").intValue());
}
}

View file

@ -0,0 +1,18 @@
[[fruit]]
name = "apple"
[fruit.physical]
color = "red"
shape = "round"
[[fruit.variety]]
name = "red delicious"
[[fruit.variety]]
name = "granny smith"
[[fruit]]
name = "banana"
[[fruit.variety]]
name = "plantain"