Current section
Files
Jump to
Current section
Files
src/oas/generator/lift.gleam
import gleam/dict
import gleam/list
import non_empty_list.{NonEmptyList}
import oas
pub type Schema(t) {
Named(String)
Primitive(Primitive)
Array(Lifted)
Tuple(List(Lifted))
Compound(t)
Unsupported
}
pub type Lifted =
Schema(Int)
pub type Top =
Schema(Fields)
pub type Fields {
Fields(named: List(#(String, #(Lifted, Bool))), required: List(String))
}
pub type Primitive {
Boolean
Integer
Number
String
Null
Always
Never
}
pub fn lift(schema) {
do_lift(schema, [])
}
fn not_top(top: Top, acc) -> #(Lifted, _) {
case top {
Compound(fields) -> {
let id = list.length(acc)
let acc = [fields, ..acc]
#(Compound(id), acc)
}
Named(name) -> #(Named(name), acc)
Primitive(primitive) -> #(Primitive(primitive), acc)
Array(items) -> #(Array(items), acc)
Tuple(items) -> #(Tuple(items), acc)
Unsupported -> #(Unsupported, acc)
}
}
pub fn do_lift(schema, acc) -> #(Top, Bool, List(_)) {
case schema {
oas.Ref(ref:, ..) -> #(Named(ref), False, acc)
oas.Inline(schema) ->
case schema {
oas.Boolean(nullable:, ..) -> #(Primitive(Boolean), nullable, acc)
oas.Integer(nullable:, ..) -> #(Primitive(Integer), nullable, acc)
oas.Number(nullable:, ..) -> #(Primitive(Number), nullable, acc)
oas.String(nullable:, ..) -> #(Primitive(String), nullable, acc)
oas.Null(..) -> #(Primitive(Null), False, acc)
oas.Array(nullable:, items:, ..) -> {
let #(top, _, acc) = do_lift(items, acc)
let #(schema, acc) = not_top(top, acc)
#(Array(schema), nullable, acc)
}
oas.Object(nullable:, properties:, required:, ..) -> {
let #(acc, properties) =
list.map_fold(properties |> dict.to_list, acc, fn(acc, property) {
let #(field, schema) = property
let #(top, nullable, acc) = do_lift(schema, acc)
let #(schema, acc) = not_top(top, acc)
#(acc, #(field, #(schema, nullable)))
})
#(Compound(Fields(properties, required)), nullable, acc)
}
oas.AllOf(NonEmptyList(schema, [])) -> do_lift(schema, acc)
oas.AllOf(items) -> {
let #(acc, items) =
list.map_fold(items |> non_empty_list.to_list, acc, fn(acc, item) {
let #(top, _, acc) = do_lift(item, acc)
let #(schema, acc) = not_top(top, acc)
#(acc, schema)
})
#(Tuple(items), False, acc)
}
oas.AnyOf(NonEmptyList(schema, [])) -> do_lift(schema, acc)
oas.OneOf(NonEmptyList(schema, [])) -> do_lift(schema, acc)
oas.AnyOf(..) | oas.OneOf(..) -> #(Unsupported, False, acc)
oas.AlwaysPasses(..) -> #(Primitive(Always), False, acc)
oas.AlwaysFails(..) -> #(Primitive(Never), False, acc)
}
}
}