import gleam/dynamic/decode.{type Decoder} import gleam/json.{type Json} import gleam/option.{type Option, None, Some} pub type Encodable { Integer(Option(Int)) Text(Option(String)) Timestamptz(Option(String)) Uuid(Option(String)) } pub fn decoder() -> Decoder(Encodable) { use t <- decode.field("t", decode.string) case t { "Integer" -> { use c <- decode.field("c", decode.optional(decode.int)) decode.success(Integer(c)) } "Text" -> { use c <- decode.field("c", decode.optional(decode.string)) decode.success(Text(c)) } "Timestamptz" -> { use c <- decode.field("c", decode.optional(decode.string)) decode.success(Timestamptz(c)) } "Uuid" -> { use c <- decode.field("c", decode.optional(decode.string)) decode.success(Uuid(c)) } _ -> decode.failure(Text(Some("")), "Encodable") } } pub fn to_json(value: Encodable) -> Json { json.object([ #( "t", json.string(case value { Integer(_) -> "Integer" Text(_) -> "Text" Timestamptz(_) -> "Timestamptz" Uuid(_) -> "Uuid" }), ), #("c", case value { Integer(Some(inner)) -> json.int(inner) Integer(None) -> json.null() Text(Some(inner)) -> json.string(inner) Text(None) -> json.null() Timestamptz(Some(inner)) -> json.string(inner) Timestamptz(None) -> json.null() Uuid(Some(inner)) -> json.string(inner) Uuid(None) -> json.null() }), ]) }