Current section

Files

Jump to
gserde src gserde.gleam
Raw

src/gserde.gleam

import gleam/io
import gleam/list
import gleam/bool
import gleam/string
import gleam/result
import glance
import internal/serializer
import internal/deserializer
import simplifile
import request.{type Request, Request}
import fswalk
pub fn gen(req: Request) {
let ser =
bool.guard(when: req.ser, return: serializer.from(req), otherwise: fn() {
""
})
let de =
bool.guard(when: req.de, return: deserializer.to(req), otherwise: fn() {
""
})
#(
req,
[ser, de]
|> string.join("\n\n"),
)
}
fn to_output_filename(src_filename) {
string.replace(in: src_filename, each: ".gleam", with: "_json.gleam")
}
fn expect(x, msg) {
case x {
Ok(v) -> v
Error(_) -> {
io.print_error(msg)
panic
}
}
}
pub fn main() {
fswalk.builder()
|> fswalk.with_path("src")
|> fswalk.with_entry_filter(fswalk.only_files)
|> fswalk.walk
|> fswalk.map(fn(v) { expect(v, "failed to walk").filename })
|> fswalk.each(process_single)
}
pub fn process_single(src_filename: String) {
let src_module_name =
src_filename
|> string.replace("src/", "")
|> string.replace(".gleam", "")
let dest_filename = to_output_filename(src_filename)
let assert Ok(code) = simplifile.read(from: src_filename)
let assert Ok(parsed) =
glance.module(code)
|> result.map_error(fn(err) {
io.debug(err)
panic
})
let custom_types =
list.map(parsed.custom_types, fn(def) { def.definition })
|> list.filter(fn(x) { string.ends_with(x.name, "JSON") })
let requests =
custom_types
|> list.flat_map(fn(custom_type) {
list.map(custom_type.variants, fn(variant) {
Request(
src_module_name: src_module_name,
type_name: custom_type.name,
variant: variant,
ser: True,
de: True,
)
})
})
let filecontent =
list.map(requests, gen)
|> list.map(fn(it) { it.1 })
|> string.join("\n\n")
case filecontent {
"" -> Nil
_ ->
simplifile.write(
to: dest_filename,
contents: [
"import gleam/json",
"import gleam/dynamic",
"import " <> src_module_name,
filecontent,
]
|> string.join("\n"),
)
|> result.unwrap(Nil)
}
// foo.Foo(a: True, b: #(123))
// |> foo_json.to_string
// |> io.println
}