Merge pull request #266 from typesafehub/sorted-rendering

Apply numeric sort to object keys when rendering
This commit is contained in:
Havoc Pennington 2015-03-03 10:58:32 -05:00
commit 0783ad341a
2 changed files with 48 additions and 1 deletions

View File

@ -418,6 +418,45 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa
});
}
static final private class RenderComparator implements java.util.Comparator<String> {
private static boolean isAllDigits(String s) {
int length = s.length();
// empty string doesn't count as a number
if (length == 0)
return false;
for (int i = 0; i < length; ++i) {
char c = s.charAt(i);
if (Character.isDigit(c))
continue;
else
return false;
}
return true;
}
// This is supposed to sort numbers before strings,
// and sort the numbers numerically. The point is
// to make objects which are really list-like
// (numeric indices) appear in order.
@Override
public int compare(String a, String b) {
boolean aDigits = isAllDigits(a);
boolean bDigits = isAllDigits(b);
if (aDigits && bDigits) {
return Integer.compare(Integer.parseInt(a), Integer.parseInt(b));
} else if (aDigits) {
return -1;
} else if (bDigits) {
return 1;
} else {
return a.compareTo(b);
}
}
}
@Override
protected void render(StringBuilder sb, int indent, boolean atRoot, ConfigRenderOptions options) {
if (isEmpty()) {
@ -438,7 +477,7 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa
int separatorCount = 0;
String[] keys = keySet().toArray(new String[size()]);
Arrays.sort(keys);
Arrays.sort(keys, new RenderComparator());
for (String k : keys) {
AbstractConfigValue v;
v = value.get(k);

View File

@ -14,6 +14,7 @@ import com.typesafe.config.ConfigList
import com.typesafe.config.ConfigException
import com.typesafe.config.ConfigValueType
import com.typesafe.config.ConfigOrigin
import com.typesafe.config.ConfigRenderOptions
import com.typesafe.config.ConfigValueFactory
import com.typesafe.config.ConfigFactory
@ -959,4 +960,11 @@ class ConfigValueTest extends TestUtils {
assertEquals(conf, parsed)
}
@Test
def renderSorting(): Unit = {
val config = parseConfig("""0=a,1=b,2=c,3=d,10=e,20=f,30=g""")
val rendered = config.root.render(ConfigRenderOptions.concise())
assertEquals("""{"0":"a","1":"b","2":"c","3":"d","10":"e","20":"f","30":"g"}""", rendered)
}
}