Возможность настроить параметры парсера/дампера yaml

This commit is contained in:
Victor 2019-05-29 23:29:53 +03:00
parent 8fd7140629
commit d8fde244b0
2 changed files with 50 additions and 5 deletions

View File

@ -1,23 +1,34 @@
package com.annimon.ownlang.modules.yaml;
import com.annimon.ownlang.lib.*;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml;
public final class yaml_decode implements Function {
@Override
public Value execute(Value... args) {
Arguments.check(1, args.length);
Arguments.checkOrOr(1, 2, args.length);
try {
final String yamlRaw = args[0].asString();
final Object root = new Yaml().load(yamlRaw);
final LoaderOptions options = new LoaderOptions();
if (args.length == 2 && args[1].type() == Types.MAP) {
configure(options, ((MapValue) args[1]));
}
final Object root = new Yaml(options).load(yamlRaw);
return process(root);
} catch (Exception ex) {
throw new RuntimeException("Error while parsing yaml", ex);
}
}
private void configure(LoaderOptions options, MapValue map) {
map.ifPresent("allowDuplicateKeys", value ->
options.setAllowDuplicateKeys(value.asInt() != 0));
}
private Value process(Object obj) {
if (obj instanceof Map) {
@ -40,7 +51,7 @@ public final class yaml_decode implements Function {
}
private MapValue process(Map<Object, Object> map) {
final MapValue result = new MapValue(map.size());
final MapValue result = new MapValue(new LinkedHashMap<>(map.size()));
for (Map.Entry<Object, Object> entry : map.entrySet()) {
final String key = entry.getKey().toString();
final Value value = process(entry.getValue());

View File

@ -5,21 +5,55 @@ import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
public final class yaml_encode implements Function {
@Override
public Value execute(Value... args) {
Arguments.check(1, args.length);
Arguments.checkOrOr(1, 2, args.length);
try {
final Object root = process(args[0]);
final String yamlRaw = new Yaml().dump(root);
final DumperOptions options = new DumperOptions();
if (args.length == 2 && args[1].type() == Types.MAP) {
configure(options, ((MapValue) args[1]));
}
final String yamlRaw = new Yaml(options).dump(root);
return new StringValue(yamlRaw);
} catch (Exception ex) {
throw new RuntimeException("Error while creating yaml", ex);
}
}
private void configure(DumperOptions options, MapValue map) {
map.ifPresent("allowReadOnlyProperties", value ->
options.setAllowReadOnlyProperties(value.asInt() != 0));
map.ifPresent("allowUnicode", value ->
options.setAllowUnicode(value.asInt() != 0));
map.ifPresent("canonical", value ->
options.setCanonical(value.asInt() != 0));
map.ifPresent("defaultFlowStyle", value ->
options.setDefaultFlowStyle(DumperOptions.FlowStyle.valueOf(value.asString())));
map.ifPresent("defaultScalarStyle", value ->
options.setDefaultScalarStyle(DumperOptions.ScalarStyle.valueOf(value.asString())));
map.ifPresent("explicitEnd", value ->
options.setExplicitEnd(value.asInt() != 0));
map.ifPresent("explicitStart", value ->
options.setExplicitStart(value.asInt() != 0));
map.ifPresent("indent", value ->
options.setIndent(value.asInt()));
map.ifPresent("indicatorIndent", value ->
options.setIndicatorIndent(value.asInt()));
map.ifPresent("lineBreak", value ->
options.setLineBreak(DumperOptions.LineBreak.valueOf(value.asString())));
map.ifPresent("prettyFlow", value ->
options.setPrettyFlow(value.asInt() != 0));
map.ifPresent("splitLines", value ->
options.setSplitLines(value.asInt() != 0));
map.ifPresent("width", value ->
options.setWidth(value.asInt()));
}
private Object process(Value val) {
switch (val.type()) {