Skip to content

Commit

Permalink
yaml / json support (#32)
Browse files Browse the repository at this point in the history
* support union types

* wip

* wip json support

* implement json

* wip json and tests

* add failing tests

* full yaml implementation

* all yaml test cases pass

* json export is now valid but ill-formatted

* all tests pass for json and yaml

* correct json format with variable indentation

* fix readme

* fix last test
  • Loading branch information
winitzki authored Jul 5, 2024
1 parent 68c6a3b commit 2f8a3ca
Show file tree
Hide file tree
Showing 84 changed files with 1,425 additions and 265 deletions.
32 changes: 24 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,14 +246,14 @@ The test script should print "Tests successful." at the end. If it does not prin

```bash
$ java -jar ./dhall.jar --help
dhall.jar
java -jar dhall.jar --flags... command
-f --file <str> Path to the input Dhall file (default: stdin)
-o --output <str> Path to the output file (default: stdout)
-q --quoted Quote all strings (for Yaml output only; default is false)
-d --documents Create a Yaml file with document separators (for Yaml output only; default is
false)
-i --indent <int> Indentation depth for JSON and Yaml (default: 2)
-o --output <str> Path to the output file (default: stdout)
command <str>... Optional command: decode, encode, hash, text, type, yaml
command <str>... Optional command: decode, encode, hash, text, type, yaml, json
```

Examples:
Expand All @@ -264,13 +264,19 @@ $ java -jar ./dhall.jar --file ./scall-cli/src/test/resources/jar-tests/3.dhall
{ True = [1.23, 4.56], a = 2, b = None Bool, c = Some "abc", y = True }
```
Compute the type of a Dhall expression.
Print the inferred type of a Dhall expression.
```bash
$ java -jar ./dhall.jar --file ./scall-cli/src/test/resources/jar-tests/3.dhall type
{ True : List Double, a : Natural, b : Optional Bool, c : Optional Text, y : Bool }
```
Export a Dhall expression to Yaml format.
Compute the SHA256 hash of a Dhall expression.
```bash
$ java -jar ./dhall.jar --file ./scall-cli/src/test/resources/jar-tests/3.dhall hash
sha256:e06ccdb4df3721dba87291eb49754c87955462d73df626e5e4c77de3af06e87f
```
Export a Dhall expression to Yaml format. Default indentation is 2 spaces.
```bash
$ java -jar ./dhall.jar --file ./scall-cli/src/test/resources/jar-tests/3.dhall yaml
'True':
Expand All @@ -281,8 +287,18 @@ c: abc
'y': true
```
Compute the SHA256 hash of a Dhall expression.
Export a Dhall expression to JSON format, with 4 spaces of indentation.
```bash
$ java -jar ./dhall.jar --file ./scall-cli/src/test/resources/jar-tests/3.dhall hash
sha256:e06ccdb4df3721dba87291eb49754c87955462d73df626e5e4c77de3af06e87f
$ java -jar ./dhall.jar --file ./scall-cli/src/test/resources/jar-tests/3.dhall --indent 4 json
{
"True": [
1.23,
4.56
],
"a": 2,
"c": "abc",
"y": true
}
```
30 changes: 19 additions & 11 deletions scall-cli/src/main/scala/io/chymyst/dhall/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ object Main {
case object Dhall extends OutputMode
case object Text extends OutputMode
case object Yaml extends OutputMode
case object Json extends OutputMode
case object Decode extends OutputMode
case object Encode extends OutputMode
case object GetType extends OutputMode
Expand All @@ -34,22 +35,22 @@ object Main {
val result: Array[Byte] = valueType match {
case TypecheckResult.Valid((tpe: Expression, expr: Expression)) =>
outputMode match {
case OutputMode.Dhall => (expr.print + "\n").getBytes("UTF-8")
case OutputMode.Text =>
case OutputMode.Dhall => (expr.print + "\n").getBytes("UTF-8")
case OutputMode.Text =>
(expr.scheme match {
case ExpressionScheme.TextLiteral(List(), trailing) => trailing + "\n"
case s => s"Error: Dhall expression should have type Text but is instead: $s\n"
}).getBytes("UTF-8")
case OutputMode.Yaml =>
case OutputMode.Yaml | OutputMode.Json =>
(Yaml.toYaml(dhallFile.copy(value = expr), options) match {
case Left(value) => value + "\n"
case Right(value) => value
}).getBytes("UTF-8")
case OutputMode.Encode =>
case OutputMode.Encode =>
expr.toCBORmodel.encodeCbor2
case OutputMode.GetType =>
case OutputMode.GetType =>
(tpe.print + "\n").getBytes("UTF-8")
case OutputMode.GetHash =>
case OutputMode.GetHash =>
("sha256:" + Semantics.semanticHash(expr, Paths.get(".")) + "\n").getBytes("UTF-8")
}

Expand All @@ -67,6 +68,7 @@ object Main {
def parseArgs(args: Array[String]): OutputMode = args.lastOption match {
case Some("text") => OutputMode.Text
case Some("yaml") => OutputMode.Yaml
case Some("json") => OutputMode.Json
case Some("decode") => OutputMode.Decode
case Some("encode") => OutputMode.Encode
case Some("type") => OutputMode.GetType
Expand All @@ -77,8 +79,8 @@ object Main {
val defaultIndent = 2

// $COVERAGE-OFF$
@main // This method will be called by `ParserForMethods.runOrExist()` automatically.
def `dhall.jar`(
@main // This method will be called by `ParserForMethods.runOrExist()` automatically.
def `java -jar dhall.jar --flags... command`( // The name `dhall.jar` will be printed at the top of the help text.
@arg(short = 'f', doc = "Path to the input Dhall file (default: stdin)")
file: Option[String],
@arg(short = 'o', doc = "Path to the output file (default: stdout)")
Expand All @@ -89,7 +91,7 @@ object Main {
documents: Flag,
@arg(short = 'i', doc = "Indentation depth for JSON and Yaml (default: 2)")
indent: Option[Int],
@arg(doc = "Optional command: decode, encode, hash, text, type, yaml")
@arg(doc = "Optional command: decode, encode, hash, text, type, yaml, json")
command: Leftover[String],
): Unit = {
val (inputPath, inputStream) = file match {
Expand All @@ -102,12 +104,18 @@ object Main {
case Some(outputFile) => new FileOutputStream(outputFile)
case None => System.out
}
val outputMode = parseArgs(command.value.toArray)
process(
inputPath,
inputStream,
outputStream,
parseArgs(command.value.toArray),
YamlOptions(quoteAllStrings = quoted.value, createDocuments = documents.value, indent = indent.getOrElse(defaultIndent)),
outputMode,
YamlOptions(
quoteAllStrings = quoted.value,
createDocuments = documents.value,
indent = indent.getOrElse(defaultIndent),
jsonFormat = outputMode == OutputMode.Json,
),
)
}
def main(args: Array[String]): Unit = ParserForMethods(this).runOrExit(args)
Expand Down
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/01.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{a = < A | B>.A }
3 changes: 3 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/01.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"a": "A"
}
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/01.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a: A
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/02.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{a = < A | B : Natural>.B 123 }
3 changes: 3 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/02.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"a": 123
}
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/02.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a: 123
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/03.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{a.b = [] : List Bool }
5 changes: 5 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/03.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"a": {
"b": []
}
}
2 changes: 2 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/03.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
a:
b: []
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/04.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{a.b = {=} }
5 changes: 5 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/04.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"a": {
"b": {}
}
}
2 changes: 2 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/04.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
a:
b: {}
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/05.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{a.b ="e" }
5 changes: 5 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/05.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"a": {
"b": "e"
}
}
2 changes: 2 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/05.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
a:
b: 'e'
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/06.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{a.b ="e", a.c = "f" }
6 changes: 6 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/06.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"a": {
"b": "e",
"c": "f"
}
}
3 changes: 3 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/06.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
a:
b: 'e'
c: f
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/07.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{a = ["e"]}
5 changes: 5 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/07.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"a": [
"e"
]
}
2 changes: 2 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/07.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
a:
- 'e'
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/08.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{a = [" - c","d","e"]}
7 changes: 7 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/08.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"a": [
" - c",
"d",
"e"
]
}
4 changes: 4 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/08.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
a:
- " - c"
- d
- 'e'
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/09.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{a = "a-b: c"}
3 changes: 3 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/09.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"a": "a-b: c"
}
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/09.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a: "a-b: c"
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/10.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{a = ["-\n\"-\"", "a", "b"]}
7 changes: 7 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/10.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"a": [
"-\n\"-\"",
"a",
"b"
]
}
6 changes: 6 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/10.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
a:
- |
-
"-"
- a
- b
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/11.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[ "-\n\"-\"", "a", "b"]
5 changes: 5 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/11.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[
"-\n\"-\"",
"a",
"b"
]
5 changes: 5 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/11.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
- |
-
"-"
- a
- b
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/12.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{a = "-\n\"-\""}
3 changes: 3 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/12.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"a": "-\n\"-\""
}
3 changes: 3 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/12.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
a: |
-
"-"
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/13.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{a = "\"abc\""}
3 changes: 3 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/13.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"a": "\"abc\""
}
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/13.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a: "\"abc\""
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/14.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{a = "a-b"}
3 changes: 3 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/14.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"a": "a-b"
}
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/14.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a: a-b
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/15.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{a = "-"}
3 changes: 3 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/15.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"a": "-"
}
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/15.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a: "-"
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/16.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{a = [1, 2, 3], b= [4, 5]}
11 changes: 11 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/16.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"a": [
1,
2,
3
],
"b": [
4,
5
]
}
7 changes: 7 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/16.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
a:
- 1
- 2
- 3
b:
- 4
- 5
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/17.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{mapKey="a",mapValue=123},{mapKey="b",mapValue=456}]
4 changes: 4 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/17.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"a": 123,
"b": 456
}
2 changes: 2 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/17.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
a: 123
b: 456
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/18.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{x = Some {a = 1, b = Some 2, c = None Natural}, z = None Bool, y = {c = Some 3, d = 4}}
10 changes: 10 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/18.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"x": {
"a": 1,
"b": 2
},
"y": {
"c": 3,
"d": 4
}
}
6 changes: 6 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/18.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
x:
a: 1
b: 2
'y':
c: 3
d: 4
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/19.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{x = {a = 1, b = 2}, y = {c = 3, d = 4}}
10 changes: 10 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/19.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"x": {
"a": 1,
"b": 2
},
"y": {
"c": 3,
"d": 4
}
}
6 changes: 6 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/19.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
x:
a: 1
b: 2
'y':
c: 3
d: 4
1 change: 1 addition & 0 deletions scall-cli/src/test/resources/yaml-main-cases/20.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[Some {a = 1, b = 2}, None { a : Natural, b : Natural }, Some {a = 3, b = 4}]
11 changes: 11 additions & 0 deletions scall-cli/src/test/resources/yaml-main-cases/20.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[
{
"a": 1,
"b": 2
},
null,
{
"a": 3,
"b": 4
}
]
Loading

0 comments on commit 2f8a3ca

Please sign in to comment.