Packages
oaspec
0.45.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/resolver.gleam
import gleam/dict
import gleam/list
import gleam/option.{None, Some}
import gleam/result
import gleam/set.{type Set}
import gleam/string
import oaspec/internal/openapi/schema.{
type SchemaObject, type SchemaRef, Inline, Reference,
}
import oaspec/internal/openapi/spec.{type OpenApiSpec, type Resolved}
/// Errors during reference resolution.
pub type ResolveError {
UnresolvedRef(ref: String)
CircularRef(ref: String)
}
/// Resolve a $ref string to its schema name.
/// Example: "#/components/schemas/User" -> "User"
pub fn ref_to_name(ref: String) -> String {
ref
|> string.split("/")
|> list.last
|> result.unwrap("Unknown")
}
/// Resolve a SchemaRef to a SchemaObject, looking up $ref in components.
/// Tracks seen refs to detect circular references.
pub fn resolve_schema_ref(
schema_ref: SchemaRef,
spec: OpenApiSpec(Resolved),
) -> Result(SchemaObject, ResolveError) {
resolve_schema_ref_with_seen(schema_ref, spec, set.new())
}
/// Internal resolver that tracks visited refs for cycle detection.
fn resolve_schema_ref_with_seen(
schema_ref: SchemaRef,
spec: OpenApiSpec(Resolved),
seen: Set(String),
) -> Result(SchemaObject, ResolveError) {
case schema_ref {
Inline(schema) -> Ok(schema)
Reference(ref:, name:) -> {
case set.contains(seen, ref) {
True -> Error(CircularRef(ref:))
False -> {
let new_seen = set.insert(seen, ref)
case spec.components {
Some(components) -> {
case dict.get(components.schemas, name) {
Ok(Inline(schema)) -> Ok(schema)
Ok(Reference(ref: inner_ref, name: inner_name)) ->
resolve_schema_ref_with_seen(
Reference(ref: inner_ref, name: inner_name),
spec,
new_seen,
)
Error(_) -> Error(UnresolvedRef(ref:))
}
}
None -> Error(UnresolvedRef(ref:))
}
}
}
}
}
}