mirror of
https://github.com/plexusorg/toml4j.git
synced 2025-02-11 11:40:27 +00:00
Merge branch 'quoted_keys' into wip
Conflicts: README.md
This commit is contained in:
commit
89d2c70b15
8 changed files with 251 additions and 74 deletions
11
README.md
11
README.md
|
@ -51,6 +51,9 @@ name = "Mwanji Ezana"
|
||||||
[address]
|
[address]
|
||||||
street = "123 A Street"
|
street = "123 A Street"
|
||||||
city = "AnyVille"
|
city = "AnyVille"
|
||||||
|
|
||||||
|
[contacts]
|
||||||
|
"email address" = me@example.com
|
||||||
```
|
```
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
@ -62,6 +65,7 @@ class Address {
|
||||||
class User {
|
class User {
|
||||||
String name;
|
String name;
|
||||||
Address address;
|
Address address;
|
||||||
|
Map<String, Object> contacts;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -70,10 +74,13 @@ User user = new Toml().parse(tomlFile).to(User.class);
|
||||||
|
|
||||||
assert user.name.equals("Mwanji Ezana");
|
assert user.name.equals("Mwanji Ezana");
|
||||||
assert user.address.street.equals("123 A Street");
|
assert user.address.street.equals("123 A Street");
|
||||||
|
assert user.contacts.get("\"email address\"").equals("me@example.com");
|
||||||
```
|
```
|
||||||
|
|
||||||
Any keys not found in both the TOML and the class are ignored. Fields may be private.
|
Any keys not found in both the TOML and the class are ignored. Fields may be private.
|
||||||
|
|
||||||
|
Quoted keys cannot be mapped directly to a Java object, but they can be used as keys within a `Map`.
|
||||||
|
|
||||||
TOML primitives can be mapped to a number of Java types:
|
TOML primitives can be mapped to a number of Java types:
|
||||||
|
|
||||||
TOML | Java
|
TOML | Java
|
||||||
|
@ -105,8 +112,11 @@ You can also navigate values within a table with a compound key of the form `tab
|
||||||
|
|
||||||
Non-existent keys return null.
|
Non-existent keys return null.
|
||||||
|
|
||||||
|
When retrieving quoted keys, the quotes must be used and the key must be spelled exactly the same way, including quotes and whitespace.
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
title = "TOML Example"
|
title = "TOML Example"
|
||||||
|
"sub title" = "Now with quoted keys"
|
||||||
|
|
||||||
[database]
|
[database]
|
||||||
ports = [ 8001, 8001, 8002 ]
|
ports = [ 8001, 8001, 8002 ]
|
||||||
|
@ -139,6 +149,7 @@ title = "TOML Example"
|
||||||
Toml toml = new Toml().parse(getTomlFile());
|
Toml toml = new Toml().parse(getTomlFile());
|
||||||
|
|
||||||
String title = toml.getString("title");
|
String title = toml.getString("title");
|
||||||
|
String subTitle = toml.getString("\"sub title\"");
|
||||||
Boolean enabled = toml.getBoolean("database.enabled");
|
Boolean enabled = toml.getBoolean("database.enabled");
|
||||||
List<Long> ports = toml.getList("database.ports", Long.class);
|
List<Long> ports = toml.getList("database.ports", Long.class);
|
||||||
String password = toml.getString("database.credentials.password");
|
String password = toml.getString("database.credentials.password");
|
||||||
|
|
2
pom.xml
2
pom.xml
|
@ -7,7 +7,7 @@
|
||||||
</parent>
|
</parent>
|
||||||
<groupId>com.moandjiezana.toml</groupId>
|
<groupId>com.moandjiezana.toml</groupId>
|
||||||
<artifactId>toml4j</artifactId>
|
<artifactId>toml4j</artifactId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>0.3.2-SNAPSHOT</version>
|
||||||
<name>toml4j</name>
|
<name>toml4j</name>
|
||||||
<description>A parser for TOML</description>
|
<description>A parser for TOML</description>
|
||||||
<url>http://moandjiezana.com/toml/toml4j</url>
|
<url>http://moandjiezana.com/toml/toml4j</url>
|
||||||
|
|
102
src/main/java/com/moandjiezana/toml/Keys.java
Normal file
102
src/main/java/com/moandjiezana/toml/Keys.java
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
package com.moandjiezana.toml;
|
||||||
|
|
||||||
|
import static com.moandjiezana.toml.ValueConverterUtils.isComment;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
class Keys {
|
||||||
|
|
||||||
|
static class Key {
|
||||||
|
final String name;
|
||||||
|
final int index;
|
||||||
|
final String path;
|
||||||
|
|
||||||
|
Key(String name, int index, Key next) {
|
||||||
|
this.name = name;
|
||||||
|
this.index = index;
|
||||||
|
if (next != null) {
|
||||||
|
this.path = name + "." + next.path;
|
||||||
|
} else {
|
||||||
|
this.path = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Keys.Key[] split(String key) {
|
||||||
|
List<Key> splitKey = new ArrayList<Key>();
|
||||||
|
StringBuilder current = new StringBuilder();
|
||||||
|
char[] chars = key.toCharArray();
|
||||||
|
boolean quoted = false;
|
||||||
|
boolean indexable = true;
|
||||||
|
boolean inIndex = false;
|
||||||
|
int index = -1;
|
||||||
|
|
||||||
|
for (int i = chars.length - 1; i > -1; i--) {
|
||||||
|
char c = chars[i];
|
||||||
|
if (c == ']' && indexable) {
|
||||||
|
inIndex = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
indexable = false;
|
||||||
|
if (c == '[' && inIndex) {
|
||||||
|
inIndex = false;
|
||||||
|
index = Integer.parseInt(current.toString());
|
||||||
|
current = new StringBuilder();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (c == '"' && (i == 0 || chars[i - 1] != '\\')) {
|
||||||
|
quoted = !quoted;
|
||||||
|
indexable = false;
|
||||||
|
}
|
||||||
|
if (c != '.' || quoted) {
|
||||||
|
current.insert(0, c);
|
||||||
|
} else {
|
||||||
|
splitKey.add(0, new Key(current.toString(), index, !splitKey.isEmpty() ? splitKey.get(0) : null));
|
||||||
|
indexable = true;
|
||||||
|
index = -1;
|
||||||
|
current = new StringBuilder();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
splitKey.add(0, new Key(current.toString(), index, !splitKey.isEmpty() ? splitKey.get(0) : null));
|
||||||
|
|
||||||
|
return splitKey.toArray(new Key[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param line raw TOML iine to parse
|
||||||
|
* @return null if line is not a valid table identifier
|
||||||
|
*/
|
||||||
|
static String getTableName(String line) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
char[] chars = line.toCharArray();
|
||||||
|
boolean quoted = false;
|
||||||
|
boolean terminated = false;
|
||||||
|
|
||||||
|
for (int i = 1; i < chars.length; i++) {
|
||||||
|
char c = chars[i];
|
||||||
|
if (c == '"' && chars[i - 1] != '\\') {
|
||||||
|
quoted = !quoted;
|
||||||
|
} else if (!quoted && c == ']') {
|
||||||
|
terminated = true;
|
||||||
|
break;
|
||||||
|
} else if (!quoted && c == '[') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.append(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
String tableName = sb.toString();
|
||||||
|
|
||||||
|
if (!terminated || !isComment(line.substring(tableName.length() + 2))) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
tableName = StringConverter.STRING_PARSER.replaceUnicodeCharacters(tableName);
|
||||||
|
return tableName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Keys() {}
|
||||||
|
}
|
|
@ -75,9 +75,9 @@ class Results {
|
||||||
stack.pop();
|
stack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] tableParts = tableName.split("\\.");
|
Keys.Key[] tableParts = Keys.split(tableName);
|
||||||
for (int i = 0; i < tableParts.length; i++) {
|
for (int i = 0; i < tableParts.length; i++) {
|
||||||
String tablePart = tableParts[i];
|
String tablePart = tableParts[i].name;
|
||||||
Container currentContainer = stack.peek();
|
Container currentContainer = stack.peek();
|
||||||
if (tablePart.isEmpty()) {
|
if (tablePart.isEmpty()) {
|
||||||
errors.append("Empty implicit table: " + tableName + "!\n");
|
errors.append("Empty implicit table: " + tableName + "!\n");
|
||||||
|
|
|
@ -35,25 +35,16 @@ class StringConverter implements ValueConverter {
|
||||||
|
|
||||||
value = value.substring(1, stringTerminator);
|
value = value.substring(1, stringTerminator);
|
||||||
value = replaceUnicodeCharacters(value);
|
value = replaceUnicodeCharacters(value);
|
||||||
|
|
||||||
chars = value.toCharArray();
|
|
||||||
for (int i = 0; i < chars.length - 1; i++) {
|
|
||||||
char ch = chars[i];
|
|
||||||
char next = chars[i + 1];
|
|
||||||
|
|
||||||
if (ch == '\\' && next == '\\') {
|
|
||||||
i++;
|
|
||||||
} else if (ch == '\\' && !(next == 'b' || next == 'f' || next == 'n' || next == 't' || next == 'r' || next == '"' || next == '/' || next == '\\')) {
|
|
||||||
return INVALID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
value = replaceSpecialCharacters(value);
|
value = replaceSpecialCharacters(value);
|
||||||
|
|
||||||
|
if (value == null) {
|
||||||
|
return INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String replaceUnicodeCharacters(String value) {
|
String replaceUnicodeCharacters(String value) {
|
||||||
Matcher unicodeMatcher = UNICODE_REGEX.matcher(value);
|
Matcher unicodeMatcher = UNICODE_REGEX.matcher(value);
|
||||||
|
|
||||||
while (unicodeMatcher.find()) {
|
while (unicodeMatcher.find()) {
|
||||||
|
@ -62,7 +53,19 @@ class StringConverter implements ValueConverter {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String replaceSpecialCharacters(String value) {
|
String replaceSpecialCharacters(String value) {
|
||||||
|
char[] chars = value.toCharArray();
|
||||||
|
for (int i = 0; i < chars.length - 1; i++) {
|
||||||
|
char ch = chars[i];
|
||||||
|
char next = chars[i + 1];
|
||||||
|
|
||||||
|
if (ch == '\\' && next == '\\') {
|
||||||
|
i++;
|
||||||
|
} else if (ch == '\\' && !(next == 'b' || next == 'f' || next == 'n' || next == 't' || next == 'r' || next == '"' || next == '/' || next == '\\')) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return value.replace("\\n", "\n")
|
return value.replace("\\n", "\n")
|
||||||
.replace("\\\"", "\"")
|
.replace("\\\"", "\"")
|
||||||
.replace("\\t", "\t")
|
.replace("\\t", "\t")
|
||||||
|
|
|
@ -12,14 +12,12 @@ import java.math.BigDecimal;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
@ -33,13 +31,13 @@ import com.google.gson.JsonElement;
|
||||||
* {@link #getList(String, Class)}, {@link #getTable(String)} and {@link #getTables(String)} return empty values if there is no matching key.</p>
|
* {@link #getList(String, Class)}, {@link #getTable(String)} and {@link #getTables(String)} return empty values if there is no matching key.</p>
|
||||||
*
|
*
|
||||||
* <p>Example usage:</p>
|
* <p>Example usage:</p>
|
||||||
* <code><pre>
|
* <pre><code>
|
||||||
* Toml toml = new Toml().parse(getTomlFile());
|
* Toml toml = new Toml().parse(getTomlFile());
|
||||||
* String name = toml.getString("name");
|
* String name = toml.getString("name");
|
||||||
* Long port = toml.getLong("server.ip"); // compound key. Is equivalent to:
|
* Long port = toml.getLong("server.ip"); // compound key. Is equivalent to:
|
||||||
* Long port2 = toml.getTable("server").getLong("ip");
|
* Long port2 = toml.getTable("server").getLong("ip");
|
||||||
* MyConfig config = toml.to(MyConfig.class);
|
* MyConfig config = toml.to(MyConfig.class);
|
||||||
* </pre></code>
|
* </code></pre>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class Toml {
|
public class Toml {
|
||||||
|
@ -67,7 +65,7 @@ public class Toml {
|
||||||
/**
|
/**
|
||||||
* Populates the current Toml instance with values from file.
|
* Populates the current Toml instance with values from file.
|
||||||
*
|
*
|
||||||
* @param file
|
* @param file The File to be read
|
||||||
* @return this instance
|
* @return this instance
|
||||||
* @throws IllegalStateException If file contains invalid TOML
|
* @throws IllegalStateException If file contains invalid TOML
|
||||||
*/
|
*/
|
||||||
|
@ -82,7 +80,7 @@ public class Toml {
|
||||||
/**
|
/**
|
||||||
* Populates the current Toml instance with values from inputStream.
|
* Populates the current Toml instance with values from inputStream.
|
||||||
*
|
*
|
||||||
* @param inputStream
|
* @param inputStream Closed after it has been read.
|
||||||
* @return this instance
|
* @return this instance
|
||||||
* @throws IllegalStateException If file contains invalid TOML
|
* @throws IllegalStateException If file contains invalid TOML
|
||||||
*/
|
*/
|
||||||
|
@ -93,7 +91,7 @@ public class Toml {
|
||||||
/**
|
/**
|
||||||
* Populates the current Toml instance with values from reader.
|
* Populates the current Toml instance with values from reader.
|
||||||
*
|
*
|
||||||
* @param reader
|
* @param reader Closed after it has been read.
|
||||||
* @return this instance
|
* @return this instance
|
||||||
* @throws IllegalStateException If file contains invalid TOML
|
* @throws IllegalStateException If file contains invalid TOML
|
||||||
*/
|
*/
|
||||||
|
@ -122,7 +120,7 @@ public class Toml {
|
||||||
/**
|
/**
|
||||||
* Populates the current Toml instance with values from tomlString.
|
* Populates the current Toml instance with values from tomlString.
|
||||||
*
|
*
|
||||||
* @param tomlString
|
* @param tomlString String to be read.
|
||||||
* @return this instance
|
* @return this instance
|
||||||
* @throws IllegalStateException If tomlString is not valid TOML
|
* @throws IllegalStateException If tomlString is not valid TOML
|
||||||
*/
|
*/
|
||||||
|
@ -169,9 +167,8 @@ public class Toml {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If no value is found for key, an empty Toml instance is returned.
|
* @param key A table name, not including square brackets.
|
||||||
*
|
* @return A new Toml instance. Empty if no value is found for key.
|
||||||
* @param key
|
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Toml getTable(String key) {
|
public Toml getTable(String key) {
|
||||||
|
@ -179,8 +176,8 @@ public class Toml {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If no value is found for key, an empty list is returned.
|
* @param key Name of array of tables, not including square brackets.
|
||||||
* @param key
|
* @return An empty List if no value is found for key.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public List<Toml> getTables(String key) {
|
public List<Toml> getTables(String key) {
|
||||||
|
@ -214,7 +211,9 @@ public class Toml {
|
||||||
* <li>TOML array to {@link Set}</li>
|
* <li>TOML array to {@link Set}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @param targetClass
|
* @param targetClass Class to deserialize TOML to.
|
||||||
|
* @param <T> type of targetClass.
|
||||||
|
* @return A new instance of targetClass.
|
||||||
*/
|
*/
|
||||||
public <T> T to(Class<T> targetClass) {
|
public <T> T to(Class<T> targetClass) {
|
||||||
return to(targetClass, DEFAULT_GSON);
|
return to(targetClass, DEFAULT_GSON);
|
||||||
|
@ -245,55 +244,32 @@ public class Toml {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private Object get(String key) {
|
private Object get(String key) {
|
||||||
String[] split = key.split("\\.");
|
if (values.containsKey(key)) {
|
||||||
|
return values.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
Object current = new HashMap<String, Object>(values);
|
Object current = new HashMap<String, Object>(values);
|
||||||
|
|
||||||
for (int i = 0; i < split.length; i++) {
|
Keys.Key[] keys = Keys.split(key);
|
||||||
if (i == 0 && values.containsKey(key)) {
|
|
||||||
return values.get(key);
|
for (Keys.Key k : keys) {
|
||||||
}
|
if (k.index == -1 && current instanceof Map && ((Map<String, Object>) current).containsKey(k.path)) {
|
||||||
|
return ((Map<String, Object>) current).get(k.path);
|
||||||
String keyWithDot = join(Arrays.copyOfRange(split, i, split.length));
|
|
||||||
if (current instanceof Map && ((Map<String, Object>) current).containsKey(keyWithDot)) {
|
|
||||||
return ((Map<String, Object>) current).get(keyWithDot);
|
|
||||||
}
|
|
||||||
|
|
||||||
String splitKey = split[i];
|
|
||||||
Matcher matcher = ARRAY_INDEX_PATTERN.matcher(splitKey);
|
|
||||||
int index = -1;
|
|
||||||
|
|
||||||
if (matcher.find()) {
|
|
||||||
splitKey = matcher.group(1);
|
|
||||||
index = Integer.parseInt(matcher.group(2), 10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
current = ((Map<String, Object>) current).get(splitKey);
|
current = ((Map<String, Object>) current).get(k.name);
|
||||||
|
|
||||||
if (index > -1 && current != null) {
|
if (k.index > -1 && current != null) {
|
||||||
current = ((List<?>) current).get(index);
|
current = ((List<?>) current).get(k.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current == null) {
|
if (current == null) {
|
||||||
return defaults != null ? defaults.get(key) : null;
|
return defaults != null ? defaults.get(key) : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String join(String[] strings) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
|
|
||||||
for (String string : strings) {
|
|
||||||
sb.append(string).append('.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sb.length() > 0) {
|
|
||||||
sb.deleteCharAt(sb.length() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Toml(Toml defaults, Map<String, Object> values) {
|
private Toml(Toml defaults, Map<String, Object> values) {
|
||||||
this.values = values != null ? values : Collections.<String, Object>emptyMap();
|
this.values = values != null ? values : Collections.<String, Object>emptyMap();
|
||||||
|
|
|
@ -186,12 +186,7 @@ class TomlParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getTableName(String line) {
|
private String getTableName(String line) {
|
||||||
List<Object> resultValue = parse(parser().Table(), line);
|
return Keys.getTableName(line);
|
||||||
if (resultValue == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (String) resultValue.get(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isKeyValid(String key) {
|
private boolean isKeyValid(String key) {
|
||||||
|
|
90
src/test/java/com/moandjiezana/toml/QuotedKeysTest.java
Normal file
90
src/test/java/com/moandjiezana/toml/QuotedKeysTest.java
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
package com.moandjiezana.toml;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class QuotedKeysTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void should_accept_quoted_key_for_value() throws Exception {
|
||||||
|
Toml toml = new Toml().parse("\"127.0.0.1\" = \"localhost\" \n \"character encoding\" = \"UTF-8\" \n \"ʎǝʞ\" = \"value\"");
|
||||||
|
|
||||||
|
assertEquals("localhost", toml.getString("\"127.0.0.1\""));
|
||||||
|
assertEquals("UTF-8", toml.getString("\"character encoding\""));
|
||||||
|
assertEquals("value", toml.getString("\"ʎǝʞ\""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void should_accept_quoted_key_for_table_name() throws Exception {
|
||||||
|
Toml toml = new Toml().parse("[\"abc def\"]\n val = 1");
|
||||||
|
|
||||||
|
assertEquals(1L, toml.getTable("\"abc def\"").getLong("val").longValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void should_accept_partially_quoted_table_name() throws Exception {
|
||||||
|
Toml toml = new Toml().parse("[dog.\"tater.man\"] \n type = \"pug0\" \n[dog.tater] \n type = \"pug1\"\n[dog.tater.man] \n type = \"pug2\"");
|
||||||
|
Toml dogs = toml.getTable("dog");
|
||||||
|
|
||||||
|
assertEquals("pug0", dogs.getTable("\"tater.man\"").getString("type"));
|
||||||
|
assertEquals("pug1", dogs.getTable("tater").getString("type"));
|
||||||
|
assertEquals("pug2", dogs.getTable("tater").getTable("man").getString("type"));
|
||||||
|
assertEquals("pug0", toml.getString("dog.\"tater.man\".type"));
|
||||||
|
assertEquals("pug2", toml.getString("dog.tater.man.type"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void should_conserve_quoted_key_in_map() throws Exception {
|
||||||
|
Toml toml = new Toml().parse("[dog.\"tater.man\"] \n type = \"pug0\" \n[dog.tater] \n type = \"pug1\"\n[dog.tater.man] \n type = \"pug2\"");
|
||||||
|
Toml dogs = toml.getTable("dog");
|
||||||
|
|
||||||
|
Map<String, Map<String, Object>> map = dogs.to(Map.class);
|
||||||
|
|
||||||
|
assertEquals("pug0", map.get("\"tater.man\"").get("type"));
|
||||||
|
assertEquals("pug1", map.get("tater").get("type"));
|
||||||
|
assertEquals("pug2", ((Map<String, Object>) map.get("tater").get("man")).get("type"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void should_convert_quoted_keys_to_map_but_not_to_object_fields() throws Exception {
|
||||||
|
Quoted quoted = new Toml().parse("\"ʎǝʞ\" = \"value\" \n[map] \n \"ʎǝʞ\" = \"value\"").to(Quoted.class);
|
||||||
|
|
||||||
|
assertNull(quoted.ʎǝʞ);
|
||||||
|
assertEquals("value", quoted.map.get("\"ʎǝʞ\""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void should_support_table_array_index_with_quoted_key() throws Exception {
|
||||||
|
Toml toml = new Toml().parse("[[dog.\" type\"]] \n name = \"type0\" \n [[dog.\" type\"]] \n name = \"type1\"");
|
||||||
|
|
||||||
|
assertEquals("type0", toml.getString("dog.\" type\"[0].name"));
|
||||||
|
assertEquals("type1", toml.getString("dog.\" type\"[1].name"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void should_support_quoted_key_containing_square_brackets() throws Exception {
|
||||||
|
Toml toml = new Toml().parse("[dog.\" type[abc]\"] \n name = \"type0\" \n [dog.\" type[1]\"] \n \"name[]\" = \"type1\"");
|
||||||
|
|
||||||
|
assertEquals("type0", toml.getString("dog.\" type[abc]\".name"));
|
||||||
|
assertEquals("type1", toml.getString("dog.\" type[1]\".\"name[]\""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void should_support_quoted_key_containing_escaped_quote() throws Exception {
|
||||||
|
Toml toml = new Toml().parse("[dog.\"ty\\\"pe\"] \n \"na\\\"me\" = \"type0\"");
|
||||||
|
|
||||||
|
assertEquals("type0", toml.getString("dog.\"ty\\\"pe\".\"na\\\"me\""));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Quoted {
|
||||||
|
|
||||||
|
String ʎǝʞ;
|
||||||
|
|
||||||
|
Map<String, Object> map;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue