Skip to content

Generate Rust enum shells from spec enumerations#100

Merged
lorisleiva merged 1 commit into
mainfrom
loris/spec-gen-enumerations
Jun 10, 2026
Merged

Generate Rust enum shells from spec enumerations#100
lorisleiva merged 1 commit into
mainfrom
loris/spec-gen-enumerations

Conversation

@lorisleiva

Copy link
Copy Markdown
Member

This PR teaches the generator to emit Rust enum definitions from the spec's EnumerationSpec entries, replacing 9 previously hand-written enum shells with generated ones. The spec carries enumerations at the category level (today they all live under shared), so discovery is a simple walk over category.enumerations — no extra config and no additions to the override surface.

Each generated enum gets the standard derive set (Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize) plus #[serde(rename_all = "camelCase")]. Variants are pascalCase(spec name) in declaration order, with enum-level and variant-level docs propagated from the spec. The generator deliberately does not emit #[derive(Default)]: the spec doesn't carry a "default variant" notion, so any required Default lives in a hand-written companion file alongside the generated shell — the same generated-type / hand-written-impls split already used for Number.

Reconciling the spec with the existing Rust crate required one breaking rename: Endianness::{Big, Little} → Endianness::{Be, Le}, since the generator derives variant names directly from the spec's [be, le] rather than carrying a per-enum override. The hand-written TryFrom impls still accept both the short and long forms as input. NumberFormat variant ordering also shifts from semantic to alphabetic (matching spec order); no match site relies on the old ordering. instruction_node.rs, instruction_status_node.rs, shared/bytes_encoding.rs, and the type_nodes/{number,pre_offset,post_offset}_type_node.rs files each lose their inline enum definition and keep only the bespoke impls (constructors, TryFrom, Default) the spec can't express; two new files in shared/ hold the Default impls for InstructionLifecycle and OptionalAccountStrategy so the per-type generated/hand-written symmetry stays clean.

Workspace-wide: 1006 cargo tests pass unchanged, fmt and clippy stay clean, pnpm test grew by 6 enumPage tests (113 → 119), and pnpm generate round-trips deterministically.

lorisleiva commented Jun 10, 2026

Copy link
Copy Markdown
Member Author

Merge activity

  • Jun 10, 2:13 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jun 10, 2:29 PM UTC: Graphite rebased this pull request as part of a merge.
  • Jun 10, 2:29 PM UTC: @lorisleiva merged this pull request with Graphite.

@lorisleiva lorisleiva changed the base branch from loris/spec-gen-contextual-value to graphite-base/100 June 10, 2026 14:26
@lorisleiva lorisleiva changed the base branch from graphite-base/100 to main June 10, 2026 14:27
This PR teaches the generator to emit Rust `enum` definitions from the spec's `EnumerationSpec` entries, replacing 9 previously hand-written enum shells with generated ones. The spec carries enumerations at the category level (today they all live under `shared`), so discovery is a simple walk over `category.enumerations` — no extra config and no additions to the override surface.

Each generated enum gets the standard derive set (`Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize`) plus `#[serde(rename_all = "camelCase")]`. Variants are `pascalCase(spec name)` in declaration order, with enum-level and variant-level docs propagated from the spec. The generator deliberately does not emit `#[derive(Default)]`: the spec doesn't carry a "default variant" notion, so any required `Default` lives in a hand-written companion file alongside the generated shell — the same generated-type / hand-written-impls split already used for `Number`.

Reconciling the spec with the existing Rust crate required one breaking rename: `Endianness::{Big, Little} → Endianness::{Be, Le}`, since the generator derives variant names directly from the spec's `[be, le]` rather than carrying a per-enum override. The hand-written `TryFrom` impls still accept both the short and long forms as input. `NumberFormat` variant ordering also shifts from semantic to alphabetic (matching spec order); no `match` site relies on the old ordering. `instruction_node.rs`, `instruction_status_node.rs`, `shared/bytes_encoding.rs`, and the `type_nodes/{number,pre_offset,post_offset}_type_node.rs` files each lose their inline enum definition and keep only the bespoke impls (constructors, `TryFrom`, `Default`) the spec can't express; two new files in `shared/` hold the `Default` impls for `InstructionLifecycle` and `OptionalAccountStrategy` so the per-type generated/hand-written symmetry stays clean.

Workspace-wide: 1006 cargo tests pass unchanged, fmt and clippy stay clean, `pnpm test` grew by 6 enumPage tests (113 → 119), and `pnpm generate` round-trips deterministically.
@lorisleiva lorisleiva force-pushed the loris/spec-gen-enumerations branch from b97591f to 407b222 Compare June 10, 2026 14:28
@lorisleiva lorisleiva merged commit 4bb405f into main Jun 10, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant