mirror of
https://github.com/lightbend/config.git
synced 2025-01-30 06:00:09 +08:00
Apply numeric sort to object keys when rendering
Fixes #228 reported by @derrickburns; since we can interpret numeric keys as lists, we sort the keys numerically to make it easy to read the list value in order.
This commit is contained in:
parent
55bd472c24
commit
988c3441aa
@ -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
|
@Override
|
||||||
protected void render(StringBuilder sb, int indent, boolean atRoot, ConfigRenderOptions options) {
|
protected void render(StringBuilder sb, int indent, boolean atRoot, ConfigRenderOptions options) {
|
||||||
if (isEmpty()) {
|
if (isEmpty()) {
|
||||||
@ -438,7 +477,7 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa
|
|||||||
|
|
||||||
int separatorCount = 0;
|
int separatorCount = 0;
|
||||||
String[] keys = keySet().toArray(new String[size()]);
|
String[] keys = keySet().toArray(new String[size()]);
|
||||||
Arrays.sort(keys);
|
Arrays.sort(keys, new RenderComparator());
|
||||||
for (String k : keys) {
|
for (String k : keys) {
|
||||||
AbstractConfigValue v;
|
AbstractConfigValue v;
|
||||||
v = value.get(k);
|
v = value.get(k);
|
||||||
|
@ -14,6 +14,7 @@ import com.typesafe.config.ConfigList
|
|||||||
import com.typesafe.config.ConfigException
|
import com.typesafe.config.ConfigException
|
||||||
import com.typesafe.config.ConfigValueType
|
import com.typesafe.config.ConfigValueType
|
||||||
import com.typesafe.config.ConfigOrigin
|
import com.typesafe.config.ConfigOrigin
|
||||||
|
import com.typesafe.config.ConfigRenderOptions
|
||||||
import com.typesafe.config.ConfigValueFactory
|
import com.typesafe.config.ConfigValueFactory
|
||||||
import com.typesafe.config.ConfigFactory
|
import com.typesafe.config.ConfigFactory
|
||||||
|
|
||||||
@ -959,4 +960,11 @@ class ConfigValueTest extends TestUtils {
|
|||||||
|
|
||||||
assertEquals(conf, parsed)
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user