Skip to content

feat: generate concern-level file structures instead of one large restapi.rs - #120

Merged
dotkas merged 3 commits into
developfrom
copilot/dont-generate-giant-restapi
Aug 16, 2026
Merged

feat: generate concern-level file structures instead of one large restapi.rs#120
dotkas merged 3 commits into
developfrom
copilot/dont-generate-giant-restapi

Conversation

Copilot AI commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Generated APIs currently produce one flat restapi.rs, making larger specifications difficult to navigate. This planning PR proposes granular modules while preserving existing public paths.

  • Output layout
    • Keep restapi.rs as a re-exporting facade.
    • Separate models, server URLs, and operation-specific server/client code.
restapi.rs
restapi/
├── models.rs
├── server_urls.rs
├── operations/
├── server/
└── client/
  • Compatibility

    • Preserve imports such as restapi::Api and restapi::ListBooksResponse.
    • Retain existing flat library generation APIs.
  • Output management

    • Introduce package-aware generation, drift detection, dependency discovery, and stale-file cleanup.
    • Track generated companion files through an ownership manifest.
  • Scope

    • Derive filenames from stable operation names.
    • Defer tag-based grouping until multi-tag behavior is defined.

Copilot AI linked an issue Aug 14, 2026 that may be closed by this pull request
Copilot AI changed the title [WIP] Propose plan to split restapi.rs into smaller files Plan modular generation for Rust API packages Aug 14, 2026
Copilot AI requested a review from dotkas August 14, 2026 17:15
@dotkas
dotkas force-pushed the copilot/dont-generate-giant-restapi branch from d7b21b2 to 28a32c3 Compare August 16, 2026 08:49
@dotkas dotkas changed the title Plan modular generation for Rust API packages feat: generate concern-level file structures instead of one large restapi.rs Aug 16, 2026
@dotkas
dotkas marked this pull request as ready for review August 16, 2026 08:49
Copilot AI lite review requested due to automatic review settings August 16, 2026 08:49
@dotkas
dotkas force-pushed the copilot/dont-generate-giant-restapi branch from 28a32c3 to 7d6e493 Compare August 16, 2026 08:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 183 changed files in this pull request and generated no new comments.

Suppressed comments (1)

crates/oapi-codegen/src/package.rs:233

  • audit() returns early when package.children() is empty. That means a models-only run (or any run that currently emits a single root file) will not detect or clean up a companion directory left behind by an earlier operations-generating run with the same output stem. This can leave stale generated files on disk and lets --check pass even though leftover generated files remain beside the output.
fn audit(output_path: &Path, package: &GeneratedPackage) -> Result<Vec<PathBuf>> {
    if package.children().is_empty() {
        return Ok(Vec::new());
    }
    let directory = companion_of(output_path)?;
    let parent = output_path.parent().unwrap_or_else(|| return Path::new(""));

Copilot AI review requested due to automatic review settings August 16, 2026 10:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 183 changed files in this pull request and generated no new comments.

Suppressed comments (1)

docs/workflow.md:25

  • The module-tree example implies that models.rs, server_urls.rs, server.rs, and client.rs are always written when operations exist, but the generator only writes the modules enabled by the config (and models.rs can also be absent when models are provided via import-mapping). This can mislead users comparing their output to the documentation; consider marking these entries as conditional or rewording the example to reflect that only some modules may exist.

@dotkas
dotkas force-pushed the copilot/dont-generate-giant-restapi branch from 735739b to fbe5780 Compare August 16, 2026 14:55
Copilot AI review requested due to automatic review settings August 16, 2026 14:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 183 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings August 16, 2026 15:01
@dotkas
dotkas enabled auto-merge (squash) August 16, 2026 15:02
@dotkas
dotkas merged commit b619907 into develop Aug 16, 2026
8 checks passed
@dotkas
dotkas deleted the copilot/dont-generate-giant-restapi branch August 16, 2026 15:03
@alchemax-housekeeper

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 1.1.0-dev.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@alchemax-housekeeper

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 1.1.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 183 changed files in this pull request and generated 1 comment.

Suppressed comments (3)

docs/configuration.md:33

  • The output row says the root output file must end in .rs, but the implementation only requires an extension when the run emits operations (i.e. when it needs a companion directory). Models-only runs currently still produce a single file without needing a stem-derived directory.

Either tighten the implementation to require .rs for all runs, or adjust the docs here to make the requirement conditional on emitting operations.
docs/workflow.md:54

  • This section is otherwise using generated/restapi.rs as the canonical example, but the nesting warning switches to generated/api.rs. That makes it less clear that the same ownership rule applies to the earlier restapi example.

Consider keeping the example consistent (or using a placeholder like generated/<name>.rs).
docs/workflow.md:57

  • The sentence implies the output path always needs a .rs extension, but earlier in this doc you note that a models-only run writes a single file and has nothing to split. In the current implementation, the extension requirement only matters when operations are emitted (so a companion directory named after the file stem is needed).

Please clarify that the .rs extension is required for runs that split output (i.e. runs that emit operations).

Comment on lines +277 to +281
let text = name.logical();
let stem = if text == "mod" {
format!("{text}_")
} else {
text.to_owned()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Don't generate a single, giant restapi.rs

3 participants