Packages
oaspec
0.7.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/openapi/schema.gleam
import gleam/dict.{type Dict}
import gleam/list
import gleam/option.{type Option}
import gleam/string
/// Shared metadata for all schema types.
/// Extracted from variants to avoid duplication and ensure composition
/// schemas (allOf/oneOf/anyOf) don't lose these fields.
pub type SchemaMetadata {
SchemaMetadata(
description: Option(String),
nullable: Bool,
deprecated: Bool,
title: Option(String),
read_only: Bool,
write_only: Bool,
default: Option(String),
example: Option(String),
)
}
/// Create default metadata with no description, not nullable, not deprecated.
pub fn default_metadata() -> SchemaMetadata {
SchemaMetadata(
description: option.None,
nullable: False,
deprecated: False,
title: option.None,
read_only: False,
write_only: False,
default: option.None,
example: option.None,
)
}
/// Represents a JSON Schema object within OpenAPI 3.x.
/// This is the core building block for all type generation.
/// All variants carry shared `metadata` for description, nullable, deprecated.
pub type SchemaObject {
StringSchema(
metadata: SchemaMetadata,
format: Option(String),
enum_values: List(String),
min_length: Option(Int),
max_length: Option(Int),
pattern: Option(String),
)
IntegerSchema(
metadata: SchemaMetadata,
format: Option(String),
minimum: Option(Int),
maximum: Option(Int),
exclusive_minimum: Option(Int),
exclusive_maximum: Option(Int),
multiple_of: Option(Int),
)
NumberSchema(
metadata: SchemaMetadata,
format: Option(String),
minimum: Option(Float),
maximum: Option(Float),
exclusive_minimum: Option(Float),
exclusive_maximum: Option(Float),
multiple_of: Option(Float),
)
BooleanSchema(metadata: SchemaMetadata)
ArraySchema(
metadata: SchemaMetadata,
items: SchemaRef,
min_items: Option(Int),
max_items: Option(Int),
unique_items: Bool,
)
ObjectSchema(
metadata: SchemaMetadata,
properties: Dict(String, SchemaRef),
required: List(String),
additional_properties: Option(SchemaRef),
additional_properties_untyped: Bool,
min_properties: Option(Int),
max_properties: Option(Int),
)
AllOfSchema(metadata: SchemaMetadata, schemas: List(SchemaRef))
OneOfSchema(
metadata: SchemaMetadata,
schemas: List(SchemaRef),
discriminator: Option(Discriminator),
)
AnyOfSchema(
metadata: SchemaMetadata,
schemas: List(SchemaRef),
discriminator: Option(Discriminator),
)
}
/// A reference to a schema, either inline or via $ref.
/// Reference carries both the full $ref string and the pre-extracted name
/// (last segment) to eliminate repeated string splitting in codegen.
pub type SchemaRef {
Inline(SchemaObject)
Reference(ref: String, name: String)
}
/// Create a Reference from a $ref string, auto-extracting the name.
pub fn make_reference(ref: String) -> SchemaRef {
let name = ref_to_schema_name(ref)
Reference(ref:, name:)
}
/// Extract the schema name from a $ref string (last path segment).
/// Example: "#/components/schemas/User" -> "User"
fn ref_to_schema_name(ref: String) -> String {
case string.split(ref, "/") {
[] -> "Unknown"
segments -> {
case list.last(segments) {
Ok(name) -> name
Error(_) -> "Unknown"
}
}
}
}
/// OpenAPI discriminator for oneOf/anyOf.
pub type Discriminator {
Discriminator(property_name: String, mapping: Dict(String, String))
}
/// Get the description from any schema object.
pub fn get_description(schema: SchemaObject) -> Option(String) {
get_metadata(schema).description
}
/// Check if a schema is nullable.
pub fn is_nullable(schema: SchemaObject) -> Bool {
get_metadata(schema).nullable
}
/// Check if a schema is deprecated.
pub fn is_deprecated(schema: SchemaObject) -> Bool {
get_metadata(schema).deprecated
}
/// Extract the shared metadata from any schema variant.
pub fn get_metadata(schema: SchemaObject) -> SchemaMetadata {
case schema {
StringSchema(metadata:, ..) -> metadata
IntegerSchema(metadata:, ..) -> metadata
NumberSchema(metadata:, ..) -> metadata
BooleanSchema(metadata:) -> metadata
ArraySchema(metadata:, ..) -> metadata
ObjectSchema(metadata:, ..) -> metadata
AllOfSchema(metadata:, ..) -> metadata
OneOfSchema(metadata:, ..) -> metadata
AnyOfSchema(metadata:, ..) -> metadata
}
}