1
0
Fork 0
forked from 2sys/phonograph
phonograph/webc/src/encodable.gleam
2025-07-30 23:02:18 -07:00

57 lines
1.5 KiB
Gleam

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()
}),
])
}