Возможность задать отступ в jsonencode

This commit is contained in:
Victor 2019-05-29 19:11:53 +03:00
parent 23ed9e6d04
commit d3b5d9f059
2 changed files with 169 additions and 137 deletions

View File

@ -1,133 +1,133 @@
package com.annimon.ownlang.lib; package com.annimon.ownlang.lib;
import com.annimon.ownlang.exceptions.TypeException; import com.annimon.ownlang.exceptions.TypeException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONObject; import org.json.JSONObject;
public final class ValueUtils { public final class ValueUtils {
private ValueUtils() { } private ValueUtils() { }
public static Object toObject(Value val) { public static Object toObject(Value val) {
switch (val.type()) { switch (val.type()) {
case Types.ARRAY: case Types.ARRAY:
return toObject((ArrayValue) val); return toObject((ArrayValue) val);
case Types.MAP: case Types.MAP:
return toObject((MapValue) val); return toObject((MapValue) val);
case Types.NUMBER: case Types.NUMBER:
return val.raw(); return val.raw();
case Types.STRING: case Types.STRING:
return val.asString(); return val.asString();
default: default:
return JSONObject.NULL; return JSONObject.NULL;
} }
} }
public static Object toObject(MapValue map) { public static JSONObject toObject(MapValue map) {
final JSONObject result = new JSONObject(); final JSONObject result = new JSONObject();
for (Map.Entry<Value, Value> entry : map) { for (Map.Entry<Value, Value> entry : map) {
final String key = entry.getKey().asString(); final String key = entry.getKey().asString();
final Object value = toObject(entry.getValue()); final Object value = toObject(entry.getValue());
result.put(key, value); result.put(key, value);
} }
return result; return result;
} }
public static Object toObject(ArrayValue array) { public static JSONArray toObject(ArrayValue array) {
final JSONArray result = new JSONArray(); final JSONArray result = new JSONArray();
for (Value value : array) { for (Value value : array) {
result.put(toObject(value)); result.put(toObject(value));
} }
return result; return result;
} }
public static Value toValue(Object obj) { public static Value toValue(Object obj) {
if (obj instanceof JSONObject) { if (obj instanceof JSONObject) {
return toValue((JSONObject) obj); return toValue((JSONObject) obj);
} }
if (obj instanceof JSONArray) { if (obj instanceof JSONArray) {
return toValue((JSONArray) obj); return toValue((JSONArray) obj);
} }
if (obj instanceof String) { if (obj instanceof String) {
return new StringValue((String) obj); return new StringValue((String) obj);
} }
if (obj instanceof Number) { if (obj instanceof Number) {
return NumberValue.of(((Number) obj)); return NumberValue.of(((Number) obj));
} }
if (obj instanceof Boolean) { if (obj instanceof Boolean) {
return NumberValue.fromBoolean((Boolean) obj); return NumberValue.fromBoolean((Boolean) obj);
} }
// NULL or other // NULL or other
return NumberValue.ZERO; return NumberValue.ZERO;
} }
public static MapValue toValue(JSONObject json) { public static MapValue toValue(JSONObject json) {
final MapValue result = new MapValue(json.length()); final MapValue result = new MapValue(json.length());
final Iterator<String> it = json.keys(); final Iterator<String> it = json.keys();
while(it.hasNext()) { while(it.hasNext()) {
final String key = it.next(); final String key = it.next();
final Value value = toValue(json.get(key)); final Value value = toValue(json.get(key));
result.set(new StringValue(key), value); result.set(new StringValue(key), value);
} }
return result; return result;
} }
public static ArrayValue toValue(JSONArray json) { public static ArrayValue toValue(JSONArray json) {
final int length = json.length(); final int length = json.length();
final ArrayValue result = new ArrayValue(length); final ArrayValue result = new ArrayValue(length);
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
final Value value = toValue(json.get(i)); final Value value = toValue(json.get(i));
result.set(i, value); result.set(i, value);
} }
return result; return result;
} }
public static Number getNumber(Value value) { public static Number getNumber(Value value) {
if (value.type() == Types.NUMBER) return ((NumberValue) value).raw(); if (value.type() == Types.NUMBER) return ((NumberValue) value).raw();
return value.asInt(); return value.asInt();
} }
public static float getFloatNumber(Value value) { public static float getFloatNumber(Value value) {
if (value.type() == Types.NUMBER) return ((NumberValue) value).raw().floatValue(); if (value.type() == Types.NUMBER) return ((NumberValue) value).raw().floatValue();
return (float) value.asNumber(); return (float) value.asNumber();
} }
public static byte[] toByteArray(ArrayValue array) { public static byte[] toByteArray(ArrayValue array) {
final int size = array.size(); final int size = array.size();
final byte[] result = new byte[size]; final byte[] result = new byte[size];
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
result[i] = (byte) array.get(i).asInt(); result[i] = (byte) array.get(i).asInt();
} }
return result; return result;
} }
public static Function consumeFunction(Value value, int argumentNumber) { public static Function consumeFunction(Value value, int argumentNumber) {
return consumeFunction(value, " at argument " + (argumentNumber + 1)); return consumeFunction(value, " at argument " + (argumentNumber + 1));
} }
public static Function consumeFunction(Value value, String errorMessage) { public static Function consumeFunction(Value value, String errorMessage) {
final int type = value.type(); final int type = value.type();
if (type != Types.FUNCTION) { if (type != Types.FUNCTION) {
throw new TypeException("Function expected" + errorMessage throw new TypeException("Function expected" + errorMessage
+ ", but found " + Types.typeToString(type)); + ", but found " + Types.typeToString(type));
} }
return ((FunctionValue) value).getValue(); return ((FunctionValue) value).getValue();
} }
public static <T extends Number> MapValue collectNumberConstants(Class<?> clazz, Class<T> type) { public static <T extends Number> MapValue collectNumberConstants(Class<?> clazz, Class<T> type) {
MapValue result = new MapValue(20); MapValue result = new MapValue(20);
for (Field field : clazz.getDeclaredFields()) { for (Field field : clazz.getDeclaredFields()) {
if (!Modifier.isStatic(field.getModifiers())) continue; if (!Modifier.isStatic(field.getModifiers())) continue;
if (!field.getType().equals(type)) continue; if (!field.getType().equals(type)) continue;
try { try {
result.set(field.getName(), NumberValue.of((T) field.get(type))); result.set(field.getName(), NumberValue.of((T) field.get(type)));
} catch (IllegalAccessException ignore) { } catch (IllegalAccessException ignore) {
} }
} }
return result; return result;
} }
} }

View File

@ -1,25 +1,57 @@
package com.annimon.ownlang.modules.json; package com.annimon.ownlang.modules.json;
import com.annimon.ownlang.lib.Arguments; import com.annimon.ownlang.lib.Arguments;
import com.annimon.ownlang.lib.ArrayValue;
import com.annimon.ownlang.lib.Function; import com.annimon.ownlang.lib.Function;
import com.annimon.ownlang.lib.MapValue;
import com.annimon.ownlang.lib.StringValue; import com.annimon.ownlang.lib.StringValue;
import com.annimon.ownlang.lib.Types;
import com.annimon.ownlang.lib.Value; import com.annimon.ownlang.lib.Value;
import com.annimon.ownlang.lib.ValueUtils; import com.annimon.ownlang.lib.ValueUtils;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.json.JSONWriter;
public final class json_encode implements Function { public final class json_encode implements Function {
@Override @Override
public Value execute(Value... args) { public Value execute(Value[] args) {
Arguments.check(1, args.length); Arguments.checkOrOr(1, 2, args.length);
try { try {
final Object root = ValueUtils.toObject(args[0]); final int indent;
final String jsonRaw = JSONObject.valueToString(root); if (args.length == 2) {
indent = args[1].asInt();
} else {
indent = 0;
}
final String jsonRaw;
if (indent > 0) {
jsonRaw = format(args[0], indent);
} else {
final Object root = ValueUtils.toObject(args[0]);
jsonRaw = JSONWriter.valueToString(root);
}
return new StringValue(jsonRaw); return new StringValue(jsonRaw);
} catch (JSONException ex) { } catch (JSONException ex) {
throw new RuntimeException("Error while creating json", ex); throw new RuntimeException("Error while creating json", ex);
} }
} }
private String format(Value val, int indent) {
switch (val.type()) {
case Types.ARRAY:
return ValueUtils.toObject((ArrayValue) val).toString(indent);
case Types.MAP:
return ValueUtils.toObject((MapValue) val).toString(indent);
case Types.NUMBER:
return JSONWriter.valueToString(val.raw());
case Types.STRING:
return JSONWriter.valueToString(val.asString());
default:
return JSONWriter.valueToString(JSONObject.NULL);
}
}
} }