glow-up: Rebrand from "code generator" to "compiler". [skip ci]

This commit is contained in:
Lina Butler
2026-04-15 18:02:08 -07:00
parent 9dc15b5315
commit 9c27a2011f
13 changed files with 39 additions and 33 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ version = "0.11.0"
license = "Apache-2.0"
edition = "2024"
repository = "https://github.com/linabutler/ploidy"
keywords = ["codegen", "openapi", "swagger"]
keywords = ["openapi", "codegen", "compiler"]
rust-version = "1.89"
[workspace.dependencies]
+23 -17
View File
@@ -1,6 +1,6 @@
# Ploidy
**A compiler for polymorphic OpenAPI specs.**
**A polymorphism-aware OpenAPI compiler.**
[<img src="https://img.shields.io/crates/v/ploidy?style=for-the-badge&logo=rust" alt="crates.io" height="24">](https://crates.io/crates/ploidy)
[<img src="https://img.shields.io/github/actions/workflow/status/linabutler/ploidy/test.yml?style=for-the-badge&logo=github" alt="Build status" height="24">](https://github.com/linabutler/ploidy/actions?query=branch%3Amain)
@@ -9,7 +9,7 @@
[<img src="https://img.shields.io/docsrs/ploidy-pointer/latest?style=for-the-badge&label=pointer&logo=docs.rs" alt="ploidy-pointer Documentation" height="24">](https://docs.rs/ploidy-pointer)
[<img src="https://img.shields.io/docsrs/ploidy-util/latest?style=for-the-badge&label=util&logo=docs.rs" alt="ploidy-util Documentation" height="24">](https://docs.rs/ploidy-util)
Many OpenAPI specs use `allOf` to model inheritance, and `oneOf`, `anyOf`, and discriminators to model [polymorphic types](https://swagger.io/docs/specification/v3_0/data-models/inheritance-and-polymorphism/). These patterns are powerful, but can be tricky to support correctly, and most code generators struggle with them. Ploidy was built specifically with inheritance and polymorphism in mind, and aims to generate clean, type-safe, and idiomatic Rust that reads like what you'd write by hand.
Ploidy compiles OpenAPI specs into clean, type-safe Rust that reads like it was written by hand. It's built to handle the thornier features—like inheritance, polymorphism, inline schemas, and recursive types—that trip up most code generators.
## Table of Contents
@@ -29,7 +29,7 @@ Many OpenAPI specs use `allOf` to model inheritance, and `oneOf`, `anyOf`, and d
- [Per-resource feature gates](#per-resource-feature-gates)
* [Under the Hood](#under-the-hood)
- [The generation pipeline](#the-generation-pipeline)
- [AST-based generation](#ast-based-generation)
- [AST-based codegen](#ast-based-codegen)
- [Smart boxing](#smart-boxing)
- [Inline schemas](#inline-schemas)
- [Cargo features](#cargo-features)
@@ -79,10 +79,10 @@ This produces a ready-to-use crate that includes:
| Flag | Description |
|------|-------------|
| `-o`, `--output` | The output directory for the generated crate |
| `-o`, `--output` | Set the output directory for the generated crate |
| `-c`, `--check` | Verify the generated crate compiles |
| `--name <NAME>` | Set the crate name. If not passed, and a `Cargo.toml` already exists in the output directory, use its `package.name`; otherwise, use the output directory name |
| `--version <bump-major, bump-minor, bump-patch>` | Increment the major, minor, or patch component of the existing `package.version`. If not passed, use the existing version, or 0.1.0 for new crates |
| `--version <bump-major \| bump-minor \| bump-patch>` | Increment the major, minor, or patch component of the existing `package.version`. If not passed, use the existing version, or 0.1.0 for new crates |
#### Advanced options
@@ -205,7 +205,7 @@ For example, given a spec with `Customer`, `Order`, and `BillingInfo` schemas, w
default = ["billing-info", "customer", "order"]
billing-info = []
customer = ["billing-info"]
order = ["billing-info", "customer"]
order = ["customer"]
```
All features are enabled by default, so the generated crate works out of the box. Consumers that only need a subset of the API can pick the specific features they need:
@@ -219,21 +219,26 @@ This compiles just the `Customer` type—and its dependency, `BillingInfo`—alo
## Under the Hood
Ploidy takes a somewhat different approach to code generation. If you're curious about how it works, this section is for you!
Ploidy takes a different approach to code generation. If you're curious about how it works, this section is for you!
### The generation pipeline
Ploidy processes an OpenAPI spec in three stages:
📝 **Parsing** a JSON or YAML OpenAPI spec into Rust data structures. The parser is intentionally forgiving; Ploidy doesn't rigorously enforce OpenAPI (or JSON Schema) semantics.
📝 **Parsing** a JSON or YAML OpenAPI spec into Rust data structures. The parser is intentionally forgiving; Ploidy accepts malformed specs that stricter validators reject.
🏗️ **Constructing an IR** (intermediate representation). Ploidy constructs a type graph from the spec, which lets it answer questions like "which types can derive `Eq`, `Hash`, and `Default`?" and "which fields need `Box<T>` to break cycles?"
🏗️ **Constructing an IR** (intermediate representation). Ploidy builds a type graph from the spec, which lets it answer questions like "which types can derive `Eq`, `Hash`, and `Default`?" and "which fields need `Box<T>` to break cycles?"
✍️ **Generating code** from the IR. During the final stage, Ploidy builds proper Rust syntax trees from the type graph, prettifies the code, and writes it to disk.
✍️ **Generating code** from the IR. Ploidy creates Rust syntax trees from the type graph, prettifies the code, and writes it to disk.
### AST-based generation
### AST-based codegen
Most code generators use string templates, but Ploidy uses Rust's `syn` and `quote` crates to generate **syntax trees**. This means the generated code is syntactically valid by construction.
Ploidy builds Rust **syntax trees** directly with [`syn`](https://docs.rs/syn) and [`quote`](https://docs.rs/quote), rather than assembling code from string templates. This has two benefits:
* **Generated code is syntactically valid by construction.** Nodes are typed `syn` values, built with `parse_quote!` and friends. Ploidy can't produce a crate with mismatched delimiters or malformed attributes.
* **Complex types compose cleanly.** Trait bounds, attribute macros, and nested generics combine as tokens, not concatenated strings. The generator never juggles whitespace or escaping, so hard-to-generate constructs are as reliable as simple ones.
Once the tree is built, [`prettyplease`](https://docs.rs/prettyplease) formats it into the final output.
### Smart boxing
@@ -275,7 +280,7 @@ Since `Vec<T>` is already heap-allocated, only the `parent` field needs boxing t
OpenAPI specs can define schemas directly at their point of use—in operation parameters, in request and response bodies, or nested within other schemas—rather than in the `/components/schemas` section. These are called **inline schemas**.
Many code generators treat inline schemas as untyped values (`Any` or `serde_json::Value`), but Ploidy generates the same strongly-typed models for inline schemas as it does for named schemas. Inline schemas are named based on where they occur in the spec, and are namespaced in submodules within the parent module.
Ploidy generates the same strongly-typed models for inline schemas as it does for named schemas. Inline schemas are named based on where they occur in the spec, and are namespaced in submodules within the parent module.
For example, given an operation with an inline response schema:
@@ -296,7 +301,7 @@ For example, given an operation with an inline response schema:
application/json:
schema:
type: object
required: [id, email, name]
required: [id, email]
properties:
id:
type: string
@@ -319,7 +324,8 @@ pub mod types {
pub struct GetUserResponse {
pub id: String,
pub email: String,
pub name: String,
#[serde(default, skip_serializing_if = "AbsentOr::is_absent")]
pub name: AbsentOr<String>,
}
}
```
@@ -366,6 +372,6 @@ Ploidy is inspired by, learns from, and builds on the wonderful work of:
* The OpenAPI ecosystem: **openapi-generator**, **Progenitor**, and other code generators.
* The Rust ecosystem: Tokio, Reqwest, Serde, `quote`, `syn`, and `winnow`.
* [**Petgraph**](https://crates.io/crates/petgraph), a Rust graph data structure library that's Ploidy's secret sauce.
* [**Petgraph**](https://crates.io/crates/petgraph), a Rust graph data structure library that's the backbone of Ploidy's type graph.
And yes, the name is a biology pun! [Ploidy](https://en.wikipedia.org/wiki/Ploidy) refers to the number of chromosome sets in a cell, and _polyploidy_ is when cells have many chromosome sets...and polymorphic types have many forms through inheritance.
And yes, the name is a biology pun! [Ploidy](https://en.wikipedia.org/wiki/Ploidy) is the number of complete chromosome sets an organism carries—and the types Ploidy generates carry multiple sets of their own.
+2 -2
View File
@@ -1,12 +1,12 @@
[package]
name = "ploidy-codegen-rust"
description = "A Ploidy generator that emits Rust code"
description = "Rust codegen for the Ploidy OpenAPI compiler"
readme = "README.md"
keywords = ["openapi", "rust", "codegen", "compiler"]
version.workspace = true
license.workspace = true
edition.workspace = true
repository.workspace = true
keywords.workspace = true
rust-version.workspace = true
[dependencies]
+1 -1
View File
@@ -1,6 +1,6 @@
# ploidy-codegen-rust
This crate is part of the [Ploidy](https://crates.io/crates/ploidy) OpenAPI code generator. It transforms [**ploidy-core**](https://crates.io/crates/ploidy-core) types into Rust syntax trees, pretty-prints them, and saves the output to disk.
This crate is part of the [Ploidy](https://crates.io/crates/ploidy) OpenAPI compiler. It transforms [**ploidy-core**](https://crates.io/crates/ploidy-core) types into Rust syntax trees, pretty-prints them, and saves the output to disk.
⚠️ The **ploidy-codegen-rust** API isn't stable yet.
+2 -2
View File
@@ -1,12 +1,12 @@
[package]
name = "ploidy-core"
description = "An OpenAPI IR and type graph for Ploidy"
description = "IR and type graph for the Ploidy OpenAPI compiler"
readme = "README.md"
keywords = ["openapi", "codegen", "compiler", "ir", "schema"]
version.workspace = true
license.workspace = true
edition.workspace = true
repository.workspace = true
keywords.workspace = true
rust-version.workspace = true
[dependencies]
+1 -1
View File
@@ -1,5 +1,5 @@
# ploidy-core
This crate is the nucleus (🧬) of the [Ploidy](https://crates.io/crates/ploidy) OpenAPI code generator. It exposes structures for constructing a language-agnostic **intermediate representation** of an OpenAPI spec, which code generators then use to target different languages.
This crate is the core of the [Ploidy](https://crates.io/crates/ploidy) OpenAPI compiler. It exposes structures for constructing a language-agnostic **intermediate representation** of an OpenAPI spec, which codegen backends then use to target different languages.
⚠️ The **ploidy-core** API isn't stable yet.
+3 -3
View File
@@ -1,9 +1,9 @@
//! Language-agnostic intermediate representation and type graph
//! for OpenAPI code generation.
//! for the Ploidy OpenAPI compiler.
//!
//! **ploidy-core** transforms a parsed OpenAPI document into a
//! typed dependency graph that **ploidy-codegen-\*** backends
//! traverse to emit code.
//! typed dependency graph that codegen backends traverse to emit
//! code.
//!
//! # Pipeline
//!
+1 -1
View File
@@ -2,7 +2,7 @@
name = "ploidy-pointer-derive"
description = "Derive macros for Ploidy JSON Pointers"
readme = "README.md"
keywords = ["6901", "json", "json-pointer", "rfc-6901"]
keywords = ["json-pointer", "derive", "proc-macro", "macro"]
rust-version = "1.86"
version.workspace = true
license.workspace = true
+1 -1
View File
@@ -2,7 +2,7 @@
name = "ploidy-pointer"
description = "JSON Pointers for strongly-typed data structures"
readme = "README.md"
keywords = ["6901", "json", "json-pointer", "rfc-6901"]
keywords = ["json-pointer", "json-schema", "rfc6901", "json", "pointer"]
rust-version = "1.86"
version.workspace = true
license.workspace = true
+1 -1
View File
@@ -2,7 +2,7 @@
This crate provides a way to traverse typed Rust data structures using JSON Pointers ([RFC 6901](https://datatracker.ietf.org/doc/html/rfc6901)). At its heart is the `JsonPointee` trait, which can be implemented on types to make them traversable.
**ploidy-pointer** is part of the [Ploidy](https://crates.io/crates/ploidy) OpenAPI code generator, but can be used standalone.
**ploidy-pointer** is part of the [Ploidy](https://crates.io/crates/ploidy) OpenAPI compiler, but can be used standalone.
## Features
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "ploidy-util"
description = "Shared types and functions for crates generated by Ploidy"
description = "Runtime support for crates generated by Ploidy"
readme = "README.md"
rust-version = "1.86"
version.workspace = true
+1 -1
View File
@@ -1,3 +1,3 @@
# Ploidy
This package contains shared types and functions for crates generated by the [Ploidy](https://crates.io/crates/ploidy) OpenAPI code generator.
Runtime support for crates generated by the [Ploidy](https://crates.io/crates/ploidy) OpenAPI compiler.
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "ploidy"
description = "A compiler for polymorphic OpenAPI specs"
description = "A polymorphism-aware OpenAPI compiler"
readme = "README.md"
version.workspace = true
license.workspace = true