Files

73 lines
2.4 KiB
Java

package vn.sis.appointment;
import java.util.Collection;
import java.util.Map;
final class Json {
private Json() {
}
static String stringify(Object value) {
if (value == null) {
return "null";
}
if (value instanceof String text) {
return quote(text);
}
if (value instanceof Number || value instanceof Boolean) {
return value.toString();
}
if (value instanceof Map<?, ?> map) {
StringBuilder builder = new StringBuilder("{");
boolean first = true;
for (Map.Entry<?, ?> entry : map.entrySet()) {
if (!first) {
builder.append(',');
}
first = false;
builder.append(quote(String.valueOf(entry.getKey())))
.append(':')
.append(stringify(entry.getValue()));
}
return builder.append('}').toString();
}
if (value instanceof Collection<?> collection) {
StringBuilder builder = new StringBuilder("[");
boolean first = true;
for (Object item : collection) {
if (!first) {
builder.append(',');
}
first = false;
builder.append(stringify(item));
}
return builder.append(']').toString();
}
return quote(value.toString());
}
static String quote(String value) {
StringBuilder builder = new StringBuilder(value.length() + 16).append('"');
for (int i = 0; i < value.length(); i++) {
char ch = value.charAt(i);
switch (ch) {
case '"' -> builder.append("\\\"");
case '\\' -> builder.append("\\\\");
case '\b' -> builder.append("\\b");
case '\f' -> builder.append("\\f");
case '\n' -> builder.append("\\n");
case '\r' -> builder.append("\\r");
case '\t' -> builder.append("\\t");
default -> {
if (ch < 0x20) {
builder.append(String.format("\\u%04x", (int) ch));
} else {
builder.append(ch);
}
}
}
}
return builder.append('"').toString();
}
}