+38
-2
README.md
+38
-2
README.md
···
1
1
# cymbal
2
2
3
+
Build YAML in Gleam!
4
+
3
5
[](https://hex.pm/packages/cymbal)
4
6
[](https://hexdocs.pm/cymbal/)
5
7
···
7
9
gleam add cymbal
8
10
```
9
11
```gleam
10
-
import cymbal
12
+
import cymbal.{block, array, string, int}
11
13
12
14
pub fn main() {
13
-
// TODO: An example of the project in use
15
+
let document =
16
+
block([
17
+
#("apiVersion", string("v1")),
18
+
#("kind", string("Pod")),
19
+
#("metadata", block([#("name", string("example-pod"))])),
20
+
#(
21
+
"spec",
22
+
block([
23
+
#(
24
+
"containers",
25
+
array([
26
+
block([
27
+
#("name", string("example-container")),
28
+
#("image", string("nginx")),
29
+
#("ports", array([block([#("containerPort", int(80))])])),
30
+
]),
31
+
]),
32
+
),
33
+
]),
34
+
),
35
+
])
36
+
37
+
cymbal.encode(document)
38
+
// ---
39
+
// apiVersion: v1
40
+
// kind: Pod
41
+
// metadata:
42
+
// name: example-pod
43
+
// spec:
44
+
// containers:
45
+
// - name: example-container
46
+
// image: nginx
47
+
// ports:
48
+
// - containerPort: 80
49
+
)
14
50
}
15
51
```
16
52
+7
-11
gleam.toml
+7
-11
gleam.toml
···
1
1
name = "cymbal"
2
2
version = "1.0.0"
3
-
4
-
# Fill out these fields if you intend to generate HTML documentation or publish
5
-
# your project to the Hex package manager.
6
-
#
7
-
# description = ""
8
-
# licences = ["Apache-2.0"]
9
-
# repository = { type = "github", user = "username", repo = "project" }
10
-
# links = [{ title = "Website", href = "https://gleam.run" }]
11
-
#
12
-
# For a full reference of all the available options, you can have a look at
13
-
# https://gleam.run/writing-gleam/gleam-toml/.
3
+
description = "Build YAML in Gleam!"
4
+
licences = ["Apache-2.0"]
5
+
repository = { type = "github", user = "lpil", repo = "cymbal" }
6
+
links = [
7
+
{ title = "Website", href = "https://gleam.run" },
8
+
{ title = "Sponsor", href = "https://github.com/sponsors/lpil" },
9
+
]
14
10
15
11
[dependencies]
16
12
gleam_stdlib = "~> 0.34 or ~> 1.0"
+13
-3
src/cymbal.gleam
+13
-3
src/cymbal.gleam
···
7
7
///
8
8
pub opaque type Yaml {
9
9
Int(Int)
10
+
Bool(Bool)
10
11
Float(Float)
11
12
String(String)
12
13
Array(List(Yaml))
···
17
18
///
18
19
pub fn encode(doc: Yaml) -> String {
19
20
let start = case doc {
20
-
Int(_) | Float(_) | String(_) -> "---\n"
21
+
Bool(_) | Int(_) | Float(_) | String(_) -> "---\n"
21
22
Array(_) | Block(_) -> "---"
22
23
}
23
24
24
25
en(start, 0, doc) <> "\n"
25
26
}
26
27
28
+
/// Create a YAML document from a bool.
29
+
///
30
+
pub fn bool(i: Bool) -> Yaml {
31
+
Bool(i)
32
+
}
33
+
27
34
/// Create a YAML document from an int.
28
35
///
29
36
pub fn int(i: Int) -> Yaml {
···
56
63
57
64
fn en(acc: String, in: Int, doc: Yaml) -> String {
58
65
case doc {
66
+
Bool(True) -> acc <> "true"
67
+
Bool(False) -> acc <> "false"
59
68
Int(i) -> acc <> int.to_string(i)
60
69
Float(i) -> acc <> float.to_string(i)
61
70
String(i) -> en_string(acc, i)
···
73
82
|> string.append("\n")
74
83
|> indent(in)
75
84
let acc = case doc {
76
-
Int(_) | Float(_) | String(_) -> en(acc <> "- ", in + 1, doc)
85
+
Bool(_) | Int(_) | Float(_) | String(_) -> en(acc <> "- ", in + 1, doc)
77
86
Array(_) -> en(acc <> "-", in + 1, doc)
78
87
Block(docs) -> en_block(acc <> "- ", in + 1, False, docs)
79
88
}
···
107
116
108
117
fn block_child(acc: String, in: Int, doc: Yaml) -> String {
109
118
case doc {
110
-
Int(_) | Float(_) | String(_) -> en(acc <> ": ", in, doc)
119
+
Bool(_) | Int(_) | Float(_) | String(_) -> en(acc <> ": ", in, doc)
111
120
Array(_) -> en(acc <> ":", in, doc)
112
121
Block(i) -> en_block(acc <> ":", in + 1, True, i)
113
122
}
···
119
128
120
129
fn is_simple_string(s: String) -> Bool {
121
130
case s {
131
+
"yes" | "no" | "on" | "off" -> False
122
132
"0" <> _
123
133
| "1" <> _
124
134
| "2" <> _
+40
test/cymbal_test.gleam
+40
test/cymbal_test.gleam
···
36
36
)
37
37
}
38
38
39
+
pub fn encode_yes_test() {
40
+
string("yes")
41
+
|> cymbal.encode
42
+
|> should.equal(
43
+
"---
44
+
\"yes\"
45
+
",
46
+
)
47
+
}
48
+
49
+
pub fn encode_no_test() {
50
+
string("no")
51
+
|> cymbal.encode
52
+
|> should.equal(
53
+
"---
54
+
\"no\"
55
+
",
56
+
)
57
+
}
58
+
59
+
pub fn encode_on_test() {
60
+
string("on")
61
+
|> cymbal.encode
62
+
|> should.equal(
63
+
"---
64
+
\"on\"
65
+
",
66
+
)
67
+
}
68
+
69
+
pub fn encode_off_test() {
70
+
string("off")
71
+
|> cymbal.encode
72
+
|> should.equal(
73
+
"---
74
+
\"off\"
75
+
",
76
+
)
77
+
}
78
+
39
79
pub fn encode_string_with_quote_test() {
40
80
string("\"")
41
81
|> cymbal.encode