Skip to content

Commit

Permalink
*New* Add parseYaml() Function (#142)
Browse files Browse the repository at this point in the history
## Description

This PR adds a new `parseYaml()` function to **sjsonnet**.

[JSONNET Reference
Doc](https://jsonnet.org/ref/stdlib.html#:~:text=yields%20%7B%20%22foo%22%3A%20%22bar%22%20%7D.-,std.parseYaml(str),-Available%20since%20version)

---
**Signed-off-by:** Rohit Agrawal <rohit.agrawal@databricks.com>

Signed-off-by: Rohit Agrawal <rohit.agrawal@databricks.com>
  • Loading branch information
agrawroh committed Aug 18, 2023
1 parent 1df3401 commit 82a6f97
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 3 deletions.
2 changes: 2 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ lazy val main = (project in file("sjsonnet"))
"com.lihaoyi" %% "scalatags" % "0.9.3",
"com.lihaoyi" %% "os-lib" % "0.7.2",
"com.lihaoyi" %% "mainargs" % "0.2.0",
"org.json" % "json" % "20211205",
"org.scala-lang.modules" %% "scala-collection-compat" % "2.4.0",
"org.tukaani" % "xz" % "1.8",
"org.yaml" % "snakeyaml" % "1.30",
),
libraryDependencies ++= Seq(
"com.lihaoyi" %% "utest" % "0.7.7",
Expand Down
4 changes: 3 additions & 1 deletion build.sc
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ class SjsonnetModule(val crossScalaVersion: String) extends Module {
millSourcePath / "src-jvm-js"
)
def ivyDeps = super.ivyDeps() ++ Agg(
ivy"org.tukaani:xz::1.8"
ivy"org.json:json:20211205",
ivy"org.tukaani:xz::1.8",
ivy"org.yaml:snakeyaml::1.30"
)
def scalacOptions = Seq("-opt:l:inline", "-opt-inline-from:sjsonnet.**")
//def compileIvyDeps = Agg( ivy"com.lihaoyi::acyclic:0.2.0")
Expand Down
3 changes: 3 additions & 0 deletions sjsonnet/src-js/sjsonnet/Platform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ object Platform {
def xzString(s: String): String = {
throw new Exception("XZ not implemented in Scala.js")
}
def yamlToJson(s: String): String = {
throw new Exception("parseYaml() not implemented in Scala.js")
}
def md5(s: String): String = {
throw new Exception("MD5 not implemented in Scala.js")
}
Expand Down
8 changes: 8 additions & 0 deletions sjsonnet/src-jvm/sjsonnet/Platform.scala
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package sjsonnet

import org.json.JSONObject

import java.io.ByteArrayOutputStream
import java.util.Base64
import java.util.zip.GZIPOutputStream
import org.tukaani.xz.LZMA2Options
import org.tukaani.xz.XZOutputStream
import org.yaml.snakeyaml.Yaml
import org.yaml.snakeyaml.constructor.Constructor

object Platform {
def gzipBytes(b: Array[Byte]): String = {
Expand All @@ -31,6 +35,10 @@ object Platform {
def xzString(s: String): String = {
xzBytes(s.getBytes())
}
def yamlToJson(yamlString: String): String = {
val yaml: java.util.LinkedHashMap[String, Object] = new Yaml(new Constructor(classOf[java.util.LinkedHashMap[String, Object]])).load(yamlString)
new JSONObject(yaml).toString()
}
def md5(s: String): String = {
java.security.MessageDigest.getInstance("MD5")
.digest(s.getBytes("UTF-8"))
Expand Down
3 changes: 3 additions & 0 deletions sjsonnet/src-native/sjsonnet/Platform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ object Platform {
def xzString(s: String): String = {
throw new Exception("XZ not implemented in Scala Native")
}
def yamlToJson(s: String): String = {
throw new Exception("parseYaml() not implemented in Scala Native")
}
def md5(s: String): String = {
throw new Exception("MD5 not implemented in Scala Native")
}
Expand Down
13 changes: 11 additions & 2 deletions sjsonnet/src/sjsonnet/Std.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ import java.nio.charset.StandardCharsets.UTF_8
import java.util.Base64
import java.util
import java.util.regex.Pattern

import sjsonnet.Expr.Member.Visibility
import sjsonnet.Expr.BinaryOp
import sjsonnet.ArrayOps._

import scala.collection.mutable
import scala.util.matching.Regex
Expand Down Expand Up @@ -611,6 +609,16 @@ class Std {
ujson.StringParser.transform(str.asString, new ValVisitor(pos))
}

private object ParseYaml extends Val.Builtin1("str") {
def evalRhs(str: Val, ev: EvalScope, pos: Position): Val = {
try {
ujson.StringParser.transform(Platform.yamlToJson(str.asString), new ValVisitor(pos))
} catch {
case _: Exception => null
}
}
}

private object Set_ extends Val.Builtin2("arr", "keyF", Array(null, Val.False(dummyPos))) {
def evalRhs(arr: Val, keyF: Val, ev: EvalScope, pos: Position): Val = {
uniqArr(pos, ev, sortArr(pos, ev, arr, keyF), keyF)
Expand Down Expand Up @@ -1183,6 +1191,7 @@ class Std {
"parseOctal" -> ParseOctal,
"parseHex" -> ParseHex,
"parseJson" -> ParseJson,
"parseYaml" -> ParseYaml,
"md5" -> MD5,
builtin("prune", "x"){ (pos, ev, s: Val) =>
def filter(x: Val) = x match{
Expand Down
15 changes: 15 additions & 0 deletions sjsonnet/test/src-jvm/sjsonnet/ParseYamlTests.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package sjsonnet

import sjsonnet.TestUtils.eval
import utest._

object ParseYamlTests extends TestSuite {
def tests: Tests = Tests {
test {
eval("std.parseYaml('foo: bar')") ==> ujson.Value("""{"foo":"bar"}""")
}
test {
eval("std.parseYaml('')") ==> ujson.Value("""{}""")
}
}
}

0 comments on commit 82a6f97

Please sign in to comment.