mirror of
https://github.com/apple/pkl.git
synced 2026-03-22 17:19:13 +01:00
Add support for rendering Bytes values with YamlRenderer (#1276)
This commit is contained in:
@@ -153,8 +153,7 @@ final class YamlRenderer implements ValueRenderer {
|
||||
|
||||
@Override
|
||||
public void visitBytes(byte[] value) {
|
||||
throw new RendererException(
|
||||
String.format("Values of type `Bytes` cannot be rendered as YAML. Value: %s", value));
|
||||
emitter.emit(YamlUtils.bytesScalar(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -180,7 +180,8 @@ public final class YamlRendererNodes {
|
||||
|
||||
@Override
|
||||
public void visitBytes(VmBytes value) {
|
||||
cannotRenderTypeAddConverter(value);
|
||||
if (!builder.isEmpty()) builder.append(' ');
|
||||
emitter.emit(value.getBytes(), currIndent, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.pkl.core.util.yaml;
|
||||
|
||||
import java.util.Base64;
|
||||
|
||||
// Useful links:
|
||||
// https://yaml-online-parser.appspot.com
|
||||
// https://github.com/FasterXML/jackson-dataformats-text/pull/201
|
||||
@@ -210,6 +212,11 @@ public abstract class YamlEmitter {
|
||||
builder.append(value);
|
||||
}
|
||||
|
||||
public final void emit(byte[] value, StringBuilder currIndent, boolean isKey) {
|
||||
builder.append("!!binary ");
|
||||
emit(Base64.getEncoder().encodeToString(value), currIndent, isKey);
|
||||
}
|
||||
|
||||
public final void emitNull() {
|
||||
builder.append("null");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -33,6 +33,9 @@ public final class YamlUtils {
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
private static final Optional<String> STRING_TAG = Optional.of(Tag.STR.toString());
|
||||
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
private static final Optional<String> BINARY_TAG = Optional.of(Tag.BINARY.toString());
|
||||
|
||||
private static final ImplicitTuple TUPLE = new ImplicitTuple(true, true);
|
||||
|
||||
private YamlUtils() {}
|
||||
@@ -56,6 +59,13 @@ public final class YamlUtils {
|
||||
return new ScalarEvent(Optional.empty(), STRING_TAG, tuple, value, scalarStyle);
|
||||
}
|
||||
|
||||
/** Constructs a {@link ScalarEvent} for emitting the given value as YAML binary. */
|
||||
public static ScalarEvent bytesScalar(byte[] value) {
|
||||
var encoded = Base64.getEncoder().encodeToString(value);
|
||||
return new ScalarEvent(
|
||||
Optional.empty(), BINARY_TAG, new ImplicitTuple(false, false), encoded, ScalarStyle.PLAIN);
|
||||
}
|
||||
|
||||
/** Constructs a {@link ScalarEvent} for emitting the given value in plain style. */
|
||||
public static ScalarEvent plainScalar(String value, Tag tag) {
|
||||
return new ScalarEvent(
|
||||
|
||||
@@ -18,6 +18,9 @@ res13 = new Dynamic { name = "pigeon"; age = 30 }
|
||||
res14 = new Person { name = "pigeon" }
|
||||
res15 = null
|
||||
res16 = Pair(1, 2)
|
||||
res17 = Bytes()
|
||||
res18 = Bytes(1, 2, 3)
|
||||
res19 = IntSeq(0, 127).toList().toBytes()
|
||||
|
||||
output {
|
||||
renderer = new YamlRenderer {
|
||||
|
||||
@@ -18,6 +18,7 @@ res13 = new Dynamic { name = "pigeon"; age = 30 }
|
||||
res14 = new Person { name = "pigeon"; age = 30 }
|
||||
res15 = null
|
||||
res16 = Pair(1, 2)
|
||||
res17 = Bytes(1, 2, 3)
|
||||
|
||||
output {
|
||||
renderer = new YamlRenderer {
|
||||
@@ -38,6 +39,7 @@ output {
|
||||
[Null] = (it) -> "converted"
|
||||
[Pair] = (it) -> "converted"
|
||||
[IntSeq] = (it) -> "converted"
|
||||
[Bytes] = (it) -> "converted"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,3 +37,6 @@ res15: String
|
||||
res16:
|
||||
- 2
|
||||
- 3
|
||||
res17: !!binary ''
|
||||
res18: !!binary AQID
|
||||
res19: !!binary AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn8=
|
||||
|
||||
@@ -13,3 +13,4 @@ res13: converted
|
||||
res14: converted
|
||||
res15: converted
|
||||
res16: converted
|
||||
res17: converted
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -146,4 +146,36 @@ class YamlRendererTest {
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `render byte array values as binary`() {
|
||||
val evaluator = Evaluator.preconfigured()
|
||||
val module =
|
||||
evaluator.evaluate(
|
||||
ModuleSource.text(
|
||||
"""
|
||||
res1 = Bytes()
|
||||
res2 = Bytes(1, 2, 3)
|
||||
res3 = IntSeq(0, 127).toList().toBytes()
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
)
|
||||
|
||||
val writer = StringWriter()
|
||||
val renderer = ValueRenderers.yaml(writer, 2, true, false)
|
||||
|
||||
renderer.renderDocument(module)
|
||||
val output = writer.toString()
|
||||
|
||||
assertThat(output.trim())
|
||||
.isEqualTo(
|
||||
"""
|
||||
res1: !!binary ''
|
||||
res2: !!binary 'AQID'
|
||||
res3: !!binary 'AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn8='
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user