+38
-2
README.md
+38
-2
README.md
···
1
# cymbal
2
3
[](https://hex.pm/packages/cymbal)
4
[](https://hexdocs.pm/cymbal/)
5
···
7
gleam add cymbal
8
```
9
```gleam
10
-
import cymbal
11
12
pub fn main() {
13
-
// TODO: An example of the project in use
14
}
15
```
16
···
1
# cymbal
2
3
+
Build YAML in Gleam!
4
+
5
[](https://hex.pm/packages/cymbal)
6
[](https://hexdocs.pm/cymbal/)
7
···
9
gleam add cymbal
10
```
11
```gleam
12
+
import cymbal.{block, array, string, int}
13
14
pub fn main() {
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
+
)
50
}
51
```
52
+7
-11
gleam.toml
+7
-11
gleam.toml
···
1
name = "cymbal"
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/.
14
15
[dependencies]
16
gleam_stdlib = "~> 0.34 or ~> 1.0"
···
1
name = "cymbal"
2
version = "1.0.0"
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
+
]
10
11
[dependencies]
12
gleam_stdlib = "~> 0.34 or ~> 1.0"
+13
-3
src/cymbal.gleam
+13
-3
src/cymbal.gleam
···
7
///
8
pub opaque type Yaml {
9
Int(Int)
10
Float(Float)
11
String(String)
12
Array(List(Yaml))
···
17
///
18
pub fn encode(doc: Yaml) -> String {
19
let start = case doc {
20
-
Int(_) | Float(_) | String(_) -> "---\n"
21
Array(_) | Block(_) -> "---"
22
}
23
24
en(start, 0, doc) <> "\n"
25
}
26
27
/// Create a YAML document from an int.
28
///
29
pub fn int(i: Int) -> Yaml {
···
56
57
fn en(acc: String, in: Int, doc: Yaml) -> String {
58
case doc {
59
Int(i) -> acc <> int.to_string(i)
60
Float(i) -> acc <> float.to_string(i)
61
String(i) -> en_string(acc, i)
···
73
|> string.append("\n")
74
|> indent(in)
75
let acc = case doc {
76
-
Int(_) | Float(_) | String(_) -> en(acc <> "- ", in + 1, doc)
77
Array(_) -> en(acc <> "-", in + 1, doc)
78
Block(docs) -> en_block(acc <> "- ", in + 1, False, docs)
79
}
···
107
108
fn block_child(acc: String, in: Int, doc: Yaml) -> String {
109
case doc {
110
-
Int(_) | Float(_) | String(_) -> en(acc <> ": ", in, doc)
111
Array(_) -> en(acc <> ":", in, doc)
112
Block(i) -> en_block(acc <> ":", in + 1, True, i)
113
}
···
119
120
fn is_simple_string(s: String) -> Bool {
121
case s {
122
"0" <> _
123
| "1" <> _
124
| "2" <> _
···
7
///
8
pub opaque type Yaml {
9
Int(Int)
10
+
Bool(Bool)
11
Float(Float)
12
String(String)
13
Array(List(Yaml))
···
18
///
19
pub fn encode(doc: Yaml) -> String {
20
let start = case doc {
21
+
Bool(_) | Int(_) | Float(_) | String(_) -> "---\n"
22
Array(_) | Block(_) -> "---"
23
}
24
25
en(start, 0, doc) <> "\n"
26
}
27
28
+
/// Create a YAML document from a bool.
29
+
///
30
+
pub fn bool(i: Bool) -> Yaml {
31
+
Bool(i)
32
+
}
33
+
34
/// Create a YAML document from an int.
35
///
36
pub fn int(i: Int) -> Yaml {
···
63
64
fn en(acc: String, in: Int, doc: Yaml) -> String {
65
case doc {
66
+
Bool(True) -> acc <> "true"
67
+
Bool(False) -> acc <> "false"
68
Int(i) -> acc <> int.to_string(i)
69
Float(i) -> acc <> float.to_string(i)
70
String(i) -> en_string(acc, i)
···
82
|> string.append("\n")
83
|> indent(in)
84
let acc = case doc {
85
+
Bool(_) | Int(_) | Float(_) | String(_) -> en(acc <> "- ", in + 1, doc)
86
Array(_) -> en(acc <> "-", in + 1, doc)
87
Block(docs) -> en_block(acc <> "- ", in + 1, False, docs)
88
}
···
116
117
fn block_child(acc: String, in: Int, doc: Yaml) -> String {
118
case doc {
119
+
Bool(_) | Int(_) | Float(_) | String(_) -> en(acc <> ": ", in, doc)
120
Array(_) -> en(acc <> ":", in, doc)
121
Block(i) -> en_block(acc <> ":", in + 1, True, i)
122
}
···
128
129
fn is_simple_string(s: String) -> Bool {
130
case s {
131
+
"yes" | "no" | "on" | "off" -> False
132
"0" <> _
133
| "1" <> _
134
| "2" <> _
+40
test/cymbal_test.gleam
+40
test/cymbal_test.gleam
···
36
)
37
}
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
+
79
pub fn encode_string_with_quote_test() {
80
string("\"")
81
|> cymbal.encode