(OAS3-GEN) OpenAPI 3.1+ Rust Generator
// ██████╗ █████╗ ███████╗██████╗ ██████╗ ███████╗███╗ ██╗
// ██╔═══██╗██╔══██╗██╔════╝╚════██╗ ██╔════╝ ██╔════╝████╗ ██║
// ██║ ██║███████║███████╗ █████╔╝█████╗██║ ███╗█████╗ ██╔██╗ ██║
// ██║ ██║██╔══██║╚════██║ ╚═══██╗╚════╝██║ ██║██╔══╝ ██║╚██╗██║
// ╚██████╔╝██║ ██║███████║██████╔╝ ╚██████╔╝███████╗██║ ╚████║
// ╚═════╝ ╚═╝ ╚═╝╚══════╝╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═══╝
oas3-gen is a command-line interface (CLI) for generating idiomatic Rust type definitions from an OpenAPI v3.1.x specification. The tool produces clean, production-ready code designed for seamless integration into any Rust project. Its primary function is to provide a robust and reliable method for type generation, ensuring the resulting code is correct, efficient, and well-documented.
Generated output preserves the declaration order written in the OpenAPI document for schemas, fields, enum variants, union variants, operations, and header constants. Map-like generated types use indexmap::IndexMap, and arrays marked with uniqueItems: true use indexmap::IndexSet so runtime insertion order is preserved too. Pass --no-ordered-collections to opt out of the indexmap runtime types and emit std::collections::HashMap<String, T> plus Vec<T> instead.
Quick Start
1. Installation
Install the tool directly from crates.io using cargo.
Alternative build with Nix
- Make sure you have
nixinstalled or install it with:sh <(curl --proto '=https' --tlsv1.2 -L https://nixos.org/nix/install) --daemon - Now simply run it with:
nix run github:eklipse2k8/oas3-genwill run the binary, fetching the git repo automatically.- Or locally in the repo with
nix run - To globally install use
nix profile install
This takes cares of build dependencies (openssl, pkg-config) and they are packaged reproducibly and defined in flake.nix.
A development shell is included and can be accessed by running nix develop or use direnv allow if available.
2. Generation
Provide a path to an OpenAPI specification (JSON or YAML) and specify an output file for the generated Rust code. The format is auto-detected based on file extension.
# generate types (structs and enums)
# generate client operations
# generate server module (types.rs, server.rs, mod.rs)
Example
Consider the following Pet OpenAPI schema definition in fixtures/petstore.json:
Executing oas3-gen produces the corresponding Rust types.
// src/types.rs
use Deserialize;
Server Generation
The server-mod command generates an axum-based server trait with handler functions and router configuration.
This generates three files:
types.rs- All request/response typesserver.rs- Server trait, handlers, and routermod.rs- Module exports
Generated Server Trait
// server.rs
Implementing the Server
use ;
async
The generated router automatically:
- Extracts path, query, and header parameters
- Deserializes request bodies (JSON, form, multipart)
- Routes requests to the correct handler based on path and HTTP method
- Converts response enums to proper HTTP responses with status codes
Key Features
| Feature | Description |
|---|---|
| Custom Formats | Use serde_as to parse formats |
| Cycle Detection | Prevents infinite type recursion |
| Doc Comments | Schema descriptions become rustdoc |
| Enum Helpers | Ergonomic is_/as_ methods |
| Enum Modes | Merge, preserve, or relaxed |
| Event stream | Simple event stream capture if media-type is specified |
| JSON/YAML Support | Auto-detects format from file extension |
| OData Support | Optional @odata.* field handling |
| OpenAPI 3.1 | Most common spec parsing support |
| Operation Filtering | Include/exclude specific operations |
| Operation Types | Request/response type generation |
| Order Preserving | Mirrors OpenAPI declaration order in generated code |
| Schema Composition | Handles allOf/oneOf/anyOf correctly |
| Server Generation | Axum server trait scaffolding |
| Serde Integration | Automatic derive for serialization |
| Smart Naming | Auto-detects camelCase/snake_case conventions |
| Validation | Constraint attributes from spec |
| Builder Pattern | Optional bon integration for ergonomic struct construction |
| Webhooks | Generates structs from Webhook components |
Missing features
- OAS 3.1 Links and
$dynamic-ref(oas3 doesn't support this yet) - OAS 3.2 Event-stream support
- External schema references
- HTTP schema references and fetching
Command-Line Options
OpenAPI to Rust code generator
Usage: oas3-gen [OPTIONS] <COMMAND>
Commands:
list List information from OpenAPI specification
generate Generates idiomatic, type-safe Rust code from an OpenAPI v3.1 (OAS31) specification
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help
-V, --version Print version
Terminal Output:
--color <WHEN> Coloring [default: auto] [possible values: always, auto, never]
--theme <THEME> Theme [default: auto] [possible values: dark, light, auto]
Generate Command
Generates idiomatic, type-safe Rust code from an OpenAPI v3.1 (OAS31) specification
Usage: oas3-gen generate [OPTIONS] --input <FILE> [MODE]
Arguments:
[MODE] Sets the generation mode [default: types] [possible values: types, client, client-mod, server-mod]
Required:
-i, --input <FILE> Path to the OpenAPI specification file
-o, --output <PATH> Path for generated output (file for types/client, directory for client-mod/server-mod)
Code Generation:
-C, --visibility <PUB> Module visibility for generated items [default: public] [possible values: public, crate, file]
--odata-support Enable OData-specific field optionality rules (makes @odata.* fields optional on concrete types)
--enum-mode <ENUM_MODE> Specifies how to handle enum case sensitivity and duplicates [default: merge] [possible values: merge, preserve, relaxed]
--no-helpers Disable generation of ergonomic helper methods for enum variants
-c, --customize <TYPE=PATH> Custom serde_as type overrides (format: type_name=custom::Path)
--all-headers Emit header constants for all parameters defined in components, not just those used in operations
--enable-builders Enable bon builder derives on schema structs and builder methods on request structs
--doc-format Format documentation comments using mdformat (requires mdformat installed)
--no-ordered-collections Emit std::collections::HashMap and Vec instead of indexmap::IndexMap/IndexSet for map fields and uniqueItems arrays
Operation Filtering:
--only <id_1,id_2,...> Include only the specified comma-separated operation IDs
--exclude <id_1,id_2,...> Exclude the specified comma-separated operation IDs
--all-schemas Generate all schemas, even those unreferenced by selected operations
List Command
List information from OpenAPI specification
Usage: oas3-gen list [OPTIONS] <COMMAND>
Commands:
operations List all operations defined in the OpenAPI specification
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help
-V, --version Print version
Terminal Output:
--color <WHEN> Coloring [default: auto] [possible values: always, auto, never]
--theme <THEME> Theme [default: auto] [possible values: dark, light, auto]
Examples
# Basic usage to generate a client module from a json schema file
# Generate a server module with axum trait scaffolding
# Or generate types and client code individually ...
# Generate types with crate-level visibility
# Generate all schemas types including unused ones
# Generate code for specific operation types only
# Generate code excluding certain operation types
# Generate all schemas but only specific operation types (includes unreferenced schemas)
# Enable OData support for Microsoft Graph
# Enable relaxed (case-insensitive) enum deserialization
# Enable custom parsing through serde_as traits
# Enable bon builder derives for ergonomic struct construction
# Opt out of indexmap runtime types (emit std::collections::HashMap and Vec)
# Format documentation comments with mdformat
# List all operations in the specification
Documentation Formatting with mdformat
The --doc-format flag pipes generated documentation comments through
mdformat, a CommonMark-compliant
Markdown formatter. This reformats long descriptions from OpenAPI summary and
description fields into consistently wrapped, readable rustdoc comments. Lines are wrapped at 100 characters and markdown structure (headings, blockquotes, lists) is normalized.
The mdformat binary must be available on your PATH when using --doc-format.
If it is not installed, the command will fail with an error. The flag is entirely
optional and has no effect on the structure or correctness of generated code.
License
This project is licensed under the MIT License. See the LICENSE.md file for details.
Copyright (c) 2026 Individual contributors
Contribution
Contributions are welcome! Please see CONTRIBUTING.md for more details on how to get started.
All contributions submitted for inclusion in the work must be code-signed by an active HUMAN GitHub account and shall be licensed as MIT, without any additional terms or conditions. No bot or agent generated contributions will be accepted and will be immediately rejected.
See [OpenAPI v3.1.2]: https://spec.openapis.org/oas/v3.1.2