diff options
-rw-r--r-- | src/gleam/json.gleam | 62 | ||||
-rw-r--r-- | src/gleam/json/types.gleam | 1 | ||||
-rw-r--r-- | test/gleam/json_test.gleam | 23 |
3 files changed, 84 insertions, 2 deletions
diff --git a/src/gleam/json.gleam b/src/gleam/json.gleam index e1e465b..1c53e3c 100644 --- a/src/gleam/json.gleam +++ b/src/gleam/json.gleam @@ -1,8 +1,11 @@ import gleam/dynamic.{Dynamic} +import gleam/map +import gleam/option.{Option} import gleam/result import gleam/json/types -pub type Json = types.Json +pub type Json = + types.Json external fn jsone_decode(String) -> types.DecodeResult = "jsone_decode" "decode" @@ -13,3 +16,60 @@ pub fn decode(encoded: String) -> Result(Json, Dynamic) { types.Error(types.Badarg(reason)) -> Error(reason) } } + +external fn jsone_encode(Json) -> Result(String, types.DecodeResult) = + "jsone_encode" "encode" + +pub fn encode(json: Json) -> String { + // The encoder only error if input is invalid, i.e. a PID. + // This cannot happen when passing in the the Json type. + assert Ok(encoded) = jsone_encode(json) + encoded +} + +pub fn string(input: String) -> Json { + input + |> dynamic.from() + |> dynamic.unsafe_coerce() +} + +pub fn bool(input: Bool) -> Json { + input + |> dynamic.from() + |> dynamic.unsafe_coerce() +} + +pub fn int(input: Int) -> Json { + input + |> dynamic.from() + |> dynamic.unsafe_coerce() +} + +type Null { + Null +} + +pub fn null() -> Json { + Null + |> dynamic.from() + |> dynamic.unsafe_coerce() +} + +pub fn nullable(input: Option(a), mapper: fn(a) -> Json) -> Json { + input + |> option.map(mapper) + |> option.unwrap(null()) +} + +pub fn object(entries: List(tuple(String, Json))) -> Json { + entries + |> map.from_list() + |> dynamic.from() + |> dynamic.unsafe_coerce() +} + +pub fn list(input: List(Json)) -> Json { + input + |> dynamic.from() + |> dynamic.unsafe_coerce() +} diff --git a/src/gleam/json/types.gleam b/src/gleam/json/types.gleam index 2e6c78f..ad341d0 100644 --- a/src/gleam/json/types.gleam +++ b/src/gleam/json/types.gleam @@ -1,6 +1,5 @@ import gleam/dynamic.{Dynamic} - pub external type Json pub type Failure { diff --git a/test/gleam/json_test.gleam b/test/gleam/json_test.gleam index 84f0352..25228bb 100644 --- a/test/gleam/json_test.gleam +++ b/test/gleam/json_test.gleam @@ -1,4 +1,5 @@ import gleam/dynamic +import gleam/option.{None, Some} import gleam/result import gleam/json.{Json} import gleam/should @@ -12,3 +13,25 @@ pub fn decode_test() { |> result.nil_error() |> should.equal(Error(Nil)) } + +pub fn encode_test() { + json.string("hello") + |> json.encode() + |> should.equal("\"hello\"") + + json.null() + |> json.encode() + |> should.equal("null") + + json.object([tuple("foo", json.int(5))]) + |> json.encode() + |> should.equal("{\"foo\":5}") + + json.nullable(Some(5), json.int) + |> json.encode() + |> should.equal("5") + + json.nullable(None, json.int) + |> json.encode() + |> should.equal("null") +} |