Current section

Files

Jump to
oas_generator src oas generator lookup.gleam
Raw

src/oas/generator/lookup.gleam

import gleam/list
import gleam/option.{type Option}
pub type Lookup(t) {
Lookup(ref: String, next: fn(Option(String), String) -> Lookup(t))
Done(t)
}
pub fn then(lookup: Lookup(t), next: fn(t) -> Lookup(u)) -> Lookup(u) {
case lookup {
Lookup(ref, inner) ->
Lookup(ref, fn(mod, name) { then(inner(mod, name), next) })
Done(value) -> next(value)
}
}
pub fn seq(lookups: List(Lookup(t))) -> Lookup(List(t)) {
do_seq(lookups, [])
}
fn do_seq(lookups, acc) {
case lookups {
[] -> Done(list.reverse(acc))
[Done(value), ..rest] -> do_seq(rest, [value, ..acc])
[Lookup(ref, inner), ..rest] ->
Lookup(ref, fn(mod, name) { do_seq([inner(mod, name), ..rest], acc) })
}
}
pub fn fold(
items: List(t),
initial: a,
func: fn(a, t) -> Lookup(a),
) -> Lookup(a) {
case items {
[] -> Done(initial)
[next, ..rest] -> {
use acc <- then(func(initial, next))
fold(rest, acc, func)
}
}
}
pub fn map_fold(
items: List(t),
initial: a,
func: fn(a, t) -> Lookup(#(a, b)),
) -> Lookup(#(a, List(b))) {
use #(inner, buffer) <- then(
fold(items, #(initial, []), fn(acc, item) {
let #(inner, buffer) = acc
use #(inner, next) <- then(func(inner, item))
Done(#(inner, [next, ..buffer]))
}),
)
Done(#(inner, list.reverse(buffer)))
}