Packages
oaspec
0.58.0
0.68.0
0.67.0
0.66.0
0.65.0
0.64.0
0.63.0
0.62.0
0.61.0
0.60.0
0.59.0
0.58.1
0.58.0
0.57.0
0.56.0
0.55.0
0.54.0
0.53.0
0.52.0
0.51.0
0.50.0
0.49.0
0.48.0
0.47.0
0.46.0
0.45.0
0.44.0
0.43.0
0.42.0
0.41.0
0.40.0
0.39.0
0.38.0
0.37.0
0.36.0
0.35.0
0.34.0
0.33.0
0.32.0
0.31.0
0.30.0
0.29.0
0.28.0
0.27.0
0.26.0
0.25.0
0.24.0
0.23.0
0.22.0
0.21.0
0.20.0
0.19.0
0.18.0
0.17.0
0.16.0
0.15.0
0.14.0
0.13.0
0.12.0
0.11.0
0.10.0
0.9.0
0.8.0
0.7.0
0.6.3
0.6.1
0.6.0
0.5.0
0.4.0
0.3.0
0.1.3
Generate Gleam code from OpenAPI 3.x specifications
Current section
Files
Jump to
Current section
Files
src/oaspec/internal/openapi/parser_value.gleam
//// yay → JsonValue bridge helpers used by the parsing layer.
////
//// Split out of `oaspec/internal/openapi/value` so the JsonValue type itself
//// stays target-neutral (pure Gleam, no yay/BEAM dependency) and only the
//// extraction helpers that touch yay nodes carry the BEAM-only coupling.
import gleam/dict.{type Dict}
import gleam/list
import gleam/option.{type Option, None, Some}
import oaspec/internal/openapi/value.{
type JsonValue, JsonArray, JsonBool, JsonFloat, JsonInt, JsonNull, JsonObject,
JsonString,
}
import yay
/// Convert a yay.Node to a JsonValue.
fn from_node(node: yay.Node) -> JsonValue {
case node {
yay.NodeNil -> JsonNull
yay.NodeStr(s) -> JsonString(s)
yay.NodeBool(b) -> JsonBool(b)
yay.NodeInt(i) -> JsonInt(i)
yay.NodeFloat(f) -> JsonFloat(f)
yay.NodeSeq(items) -> JsonArray(list.map(items, from_node))
yay.NodeMap(entries) ->
JsonObject(
list.filter_map(entries, fn(entry) {
let #(k, v) = entry
case k {
yay.NodeStr(key) -> Ok(#(key, from_node(v)))
_ -> Error(Nil)
}
})
|> dict.from_list,
)
}
}
/// Try to extract a JsonValue from a node at a given key.
/// Returns None if the key is absent or nil.
pub fn extract_optional(node: yay.Node, key: String) -> Option(JsonValue) {
case yay.select_sugar(from: node, selector: key) {
Ok(yay.NodeNil) -> option.None
Ok(child) -> option.Some(from_node(child))
// nolint: thrown_away_error -- yay.SelectorError here only signals absent/mismatched key; absence is represented as None
Error(_) -> option.None
}
}
/// Extract an optional bool, collapsing yay's
/// `Result(Option(Bool), _)` into a plain `Option(Bool)`.
pub fn optional_bool(node: yay.Node, key: String) -> Option(Bool) {
case yay.extract_optional_bool(node, key) {
Ok(value) -> value
// nolint: thrown_away_error -- yay extractor errors collapse to "absent" for these helpers; the explicit Diagnostic surface is a separate concern handled elsewhere
Error(_) -> None
}
}
/// Extract an optional string, collapsing yay's nested result/option.
pub fn optional_string(node: yay.Node, key: String) -> Option(String) {
case yay.extract_optional_string(node, key) {
Ok(value) -> value
// nolint: thrown_away_error -- absence is the only meaningful outcome here; see optional_bool
Error(_) -> None
}
}
/// Extract an optional int, collapsing yay's nested result/option.
pub fn optional_int(node: yay.Node, key: String) -> Option(Int) {
case yay.extract_optional_int(node, key) {
Ok(value) -> value
// nolint: thrown_away_error -- absence is the only meaningful outcome here; see optional_bool
Error(_) -> None
}
}
/// Extract an optional float, collapsing yay's nested result/option.
pub fn optional_float(node: yay.Node, key: String) -> Option(Float) {
case yay.extract_optional_float(node, key) {
Ok(value) -> value
// nolint: thrown_away_error -- absence is the only meaningful outcome here; see optional_bool
Error(_) -> None
}
}
/// Extract a bool with a default. Replaces the very common
/// `extract_optional_bool |> result.unwrap(None) |> option.unwrap(default)`
/// chain.
pub fn bool_default(node: yay.Node, key: String, default: Bool) -> Bool {
case optional_bool(node, key) {
Some(value) -> value
None -> default
}
}
/// Extract a string with a default.
pub fn string_default(node: yay.Node, key: String, default: String) -> String {
case optional_string(node, key) {
Some(value) -> value
None -> default
}
}
/// Extract a dict of JsonValues from a node at a given key.
/// Returns empty dict if key is absent.
pub fn extract_map(node: yay.Node, key: String) -> Dict(String, JsonValue) {
case yay.select_sugar(from: node, selector: key) {
Ok(yay.NodeMap(entries)) ->
list.filter_map(entries, fn(entry) {
let #(k, v) = entry
case k {
yay.NodeStr(name) -> Ok(#(name, from_node(v)))
_ -> Error(Nil)
}
})
|> dict.from_list
_ -> dict.new()
}
}