Files
pkl/stdlib/jsonnet.pkl
Jen Basch 73264e8fd1 SPICE-0024: Annotation converters (#1333)
This enables defining declarative key and/or value transformations in
cases where neither `Class`- nor path-based converters can be applied
gracefully. It is also the only way to express transforming the
resulting property names in `Typed` objects without applying a converter
to the entire containing type, which is cumbersome at best.

SPICE: https://github.com/apple/pkl-evolution/pull/26
2026-01-23 12:44:41 -08:00

129 lines
4.2 KiB
Plaintext

//===----------------------------------------------------------------------===//
// 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.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//===----------------------------------------------------------------------===//
/// A [Jsonnet](https://jsonnet.org) renderer.
@ModuleInfo { minPklVersion = "0.31.0" }
module pkl.jsonnet
/// Constructs an [ImportStr].
function ImportStr(_path: String): ImportStr = new { path = _path }
/// Constructs an [ExtVar].
function ExtVar(_name: String): ExtVar = new { name = _name }
/// Renders values as [Jsonnet](https://jsonnet.org).
///
/// Pkl values are mapped to Jsonnet values as follows:
///
/// | Pkl type | Jsonnet type |
/// | -------------- | --------------- |
/// | [Null] | null |
/// | [Boolean] | boolean |
/// | [Int] | number |
/// | [Float] | number |
/// | [String] | string |
/// | [List] | array |
/// | [Set] | array |
/// | [Map] | object |
/// | [Listing] | array |
/// | [Mapping] | object |
/// | [Dynamic] | object or array |
/// | [Typed] | object |
///
/// Some Pkl types, such as [Duration] and [DataSize], don't have a Jsonnet equivalent.
/// To render values of such types, define _output converters_ (see [Renderer.converters]).
///
/// The output is formatted according to _jsonnetfmt_.
/// To render an `importstr` construct, use [ImportStr()].
/// To render an `std.extVar()` call, use [ExtVar()].
///
/// Example:
/// ```
/// import "pkl:jsonnet"
///
/// server {
/// name = "Pigeon"
/// port = jsonnet.ExtVar("port")
/// message = jsonnet.ImportStr("/etc/motd")
/// timeout = 5.min
/// }
///
/// output {
/// renderer = new jsonnet.Renderer {}
/// converters {
/// [Duration] = (it) -> it.value + it.unit
/// }
/// }
/// ```
///
/// The [Property] annotation can be used to change how a property name renders into Jsonnet.
///
/// Example:
/// ```
/// import "pkl:jsonnet"
///
/// @jsonnet.Property { name = "wing_span" }
/// wingSpan: Int
/// ```
class Renderer extends ValueRenderer {
extension = "jsonnet"
/// The characters to use for indenting output.
///
/// If empty (`""`), renders everything on a single line.
///
/// If non-empty, renders object fields and array elements on separate lines,
/// and strings containing newlines as `|||` multiline text blocks,
/// with the given leading line [indent].
indent: String | /*Deprecated*/ Null = " "
/// Whether to omit Jsonnet object fields whose value is `null`.
omitNullProperties: Boolean = true
/// Renders [value] as a Jsonnet document.
///
/// Every Jsonnet value is a valid Jsonnet document.
external function renderDocument(value: Any): String
external function renderValue(value: Any): String
}
/// Annotate properties of classes and modules with this class to override how a [Renderer]
/// interprets a property's name.
@Since { version = "0.31.0" }
class Property extends ConvertProperty {
/// The new name to use for the annotated property when rendered by [Renderer].
name: String
render = (prop, renderer) -> if (renderer is Renderer) Pair(name, prop.value) else prop
}
/// An `importstr` construct that, when evaluated by Jsonnet, returns the content of a UTF-8 text file.
///
/// To construct an [ImportStr], use method [ImportStr()].
class ImportStr {
/// The path of the file to import.
path: String
}
/// A `std.extVar()` call that, when evaluated by Jsonnet, returns the value of an external Jsonnet variable.
///
/// To construct an [ExtVar], use method [ExtVar()].
class ExtVar {
/// The external variable's name.
name: String
}