Current section

Files

Jump to
aide_generator src aide generator.gleam
Raw

src/aide/generator.gleam

import aide/tool
import glance
import glance_printer
import gleam/dict
import gleam/list
import gleam/option.{None, Some}
import oas/generator
import oas/generator/ast
import oas/generator/schema
import oas/json_schema
// [decode.map(flip_input_decoder,Flip(_, flip_output_encode))]
fn to_schema(fields: tool.ObjectSchema) -> json_schema.Schema {
json_schema.object(fields)
}
pub fn generate(tools) {
let #(tools, specs) =
list.map(tools, fn(tool) {
let tool.Spec(name:, input:, output:, ..) = tool
#(name, [
#(name <> "_input", input |> to_schema),
#(name <> "_output", output |> to_schema),
])
})
|> list.unzip
let assert Ok(#(custom, _alias, fns)) =
schema.generate(specs |> list.flatten |> dict.from_list)
|> generator.run_single_location("#")
let imports =
[
glance.Import("gleam/dynamic/decode", None, [], []),
glance.Import("gleam/dict", None, [], []),
glance.Import("gleam/json", None, [], []),
glance.Import(
"gleam/option",
None,
[glance.UnqualifiedImport("Option", None)],
[glance.UnqualifiedImport("None", None)],
),
glance.Import("oas/generator/utils", None, [], []),
]
|> list.reverse
glance.Module(
defs(imports),
defs(custom |> list.append([collective_type(tools)])),
[],
[],
defs(list.append(fns, [name_fn(tools), encode_fn(tools)])),
)
|> glance_printer.print
}
fn defs(xs) {
list.map(xs, glance.Definition([], _))
}
fn name_fn(tools) {
glance.Function(
name: "call_name",
publicity: glance.Public,
parameters: [
glance.FunctionParameter(
label: None,
name: glance.Named("call"),
type_: None,
),
],
return: None,
body: [
glance.Expression(glance.Case(
[glance.Variable("call")],
list.map(tools, fn(tool) {
glance.Clause(
[
[
glance.PatternConstructor(
None,
ast.name_for_gleam_type(tool),
[],
True,
),
],
],
None,
glance.String(tool),
)
}),
)),
],
location: glance.Span(0, 0),
)
}
fn encode_fn(tools) {
glance.Function(
name: "call_encode",
publicity: glance.Public,
parameters: [
glance.FunctionParameter(
label: None,
name: glance.Named("call"),
type_: None,
),
],
return: None,
body: [
glance.Expression(glance.Case(
[glance.Variable("call")],
list.map(tools, fn(tool) {
glance.Clause(
[
[
glance.PatternConstructor(
None,
ast.name_for_gleam_type(tool),
[
glance.ShorthandField("input"),
],
True,
),
],
],
None,
glance.Call(
glance.Variable(ast.name_for_gleam_field_or_var(
tool <> "_input_encode",
)),
[glance.UnlabelledField(glance.Variable("input"))],
),
)
}),
)),
],
location: glance.Span(0, 0),
)
}
fn collective_type(tools) {
glance.CustomType(
"Call",
glance.Public,
False,
[],
list.map(tools, fn(tool) {
glance.Variant(ast.name_for_gleam_type(tool), [
glance.LabelledVariantField(
glance.NamedType(ast.name_for_gleam_type(tool <> "_input"), None, []),
"input",
),
glance.LabelledVariantField(
glance.FunctionType(
[
glance.NamedType(
ast.name_for_gleam_type(tool <> "_output"),
None,
[],
),
],
glance.NamedType("Dict", Some("dict"), [
glance.NamedType("String", None, []),
glance.NamedType("Any", Some("utils"), []),
]),
),
"cast",
),
])
}),
)
}