Packages
oaspec
0.50.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/util/http.gleam
import gleam/int
import gleam/list
/// Type-safe HTTP status code representation.
/// Replaces raw String status codes throughout the codebase.
pub type HttpStatusCode {
/// An exact HTTP status code, e.g. 200, 404, 500.
Status(Int)
/// A wildcard range, e.g. 2XX is StatusRange(2), 4XX is StatusRange(4).
StatusRange(Int)
/// The OpenAPI "default" catch-all response.
DefaultStatus
}
/// Parse a raw status code string from an OpenAPI spec into an HttpStatusCode.
/// Returns Error(Nil) for unrecognisable strings.
pub fn parse_status_code(code: String) -> Result(HttpStatusCode, Nil) {
case code {
"default" -> Ok(DefaultStatus)
"1XX" | "1xx" -> Ok(StatusRange(1))
"2XX" | "2xx" -> Ok(StatusRange(2))
"3XX" | "3xx" -> Ok(StatusRange(3))
"4XX" | "4xx" -> Ok(StatusRange(4))
"5XX" | "5xx" -> Ok(StatusRange(5))
_ ->
case int.parse(code) {
Ok(n) -> Ok(Status(n))
Error(_) -> Error(Nil)
}
}
}
/// Convert an HttpStatusCode back to its canonical string form.
pub fn status_code_to_string(code: HttpStatusCode) -> String {
case code {
Status(n) -> int.to_string(n)
StatusRange(n) -> int.to_string(n) <> "XX"
DefaultStatus -> "default"
}
}
/// Shared HTTP status code utilities for code generation.
/// Get a human-readable suffix for a given HTTP status code.
/// Used to build anonymous type names like "ListPetsResponseOk".
pub fn status_code_suffix(code: HttpStatusCode) -> String {
case code {
Status(200) -> "Ok"
Status(201) -> "Created"
Status(204) -> "NoContent"
Status(400) -> "BadRequest"
Status(401) -> "Unauthorized"
Status(403) -> "Forbidden"
Status(404) -> "NotFound"
Status(409) -> "Conflict"
Status(422) -> "UnprocessableEntity"
Status(500) -> "InternalServerError"
Status(n) -> "Status" <> int.to_string(n)
StatusRange(1) -> "Status1xx"
StatusRange(2) -> "Status2xx"
StatusRange(3) -> "Status3xx"
StatusRange(4) -> "Status4xx"
StatusRange(5) -> "Status5xx"
StatusRange(n) -> "Status" <> int.to_string(n) <> "xx"
DefaultStatus -> "Default"
}
}
/// Convert an HttpStatusCode to a valid Gleam case pattern.
/// Exact codes become integer literals, range codes become guard expressions,
/// and DefaultStatus becomes "_" (catch-all).
pub fn status_code_to_int_pattern(code: HttpStatusCode) -> String {
case code {
DefaultStatus -> "_"
StatusRange(n) -> {
let low = int.to_string(n * 100)
let high = int.to_string(n * 100 + 99)
"status if status >= " <> low <> " && status <= " <> high
}
Status(n) -> int.to_string(n)
}
}
/// Sort response entries so that exact codes come before ranges,
/// and ranges come before the default catch-all. This ensures
/// correct pattern matching order in generated case expressions.
pub fn sort_response_entries(
entries: List(#(HttpStatusCode, a)),
) -> List(#(HttpStatusCode, a)) {
list.sort(entries, fn(a, b) {
int.compare(status_sort_priority(a.0), status_sort_priority(b.0))
})
}
/// Convert an HttpStatusCode to an integer string for use in ServerResponse.
/// Range codes and DefaultStatus map to a representative status code.
pub fn status_code_to_int(code: HttpStatusCode) -> String {
case code {
DefaultStatus -> "500"
StatusRange(n) -> int.to_string(n * 100)
Status(n) -> int.to_string(n)
}
}
fn status_sort_priority(code: HttpStatusCode) -> Int {
case code {
DefaultStatus -> 9999
StatusRange(n) -> n * 100 + 1000
Status(n) -> n
}
}