Build YAML in Gleam!

v1.0.0

+5
CHANGELOG.md
··· 1 + # Changelog 2 + 3 + ## v1.0.0 - 2024-02-13 4 + 5 + - Initial release
+38 -2
README.md
··· 1 1 # cymbal 2 2 3 + Build YAML in Gleam! 4 + 3 5 [![Package Version](https://img.shields.io/hexpm/v/cymbal)](https://hex.pm/packages/cymbal) 4 6 [![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](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
··· 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
··· 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
··· 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