Skip to content

feat: implement readonly and writeonly - #128

Merged
dotkas merged 4 commits into
developfrom
dotkas/support-readonly-and-writeonly
Aug 23, 2026
Merged

feat: implement readonly and writeonly#128
dotkas merged 4 commits into
developfrom
dotkas/support-readonly-and-writeonly

Conversation

@dotkas

@dotkas dotkas commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Closes #105

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

Implements OpenAPI 3.0 readOnly / writeOnly semantics by treating them as directional markers (request vs response) and projecting models into request/response shapes, including split type naming (<Name>Request / <Name>Response) when a model is used in both directions (Issue #105).

Changes:

  • Introduces direction-aware model projection via a new lowering pass that splits and rewrites models and service type references based on request/response reachability.
  • Adds IR support for direction and per-field access (readOnly/writeOnly) and threads it through schema lowering and multipart lowering (including rejecting readOnly && writeOnly).
  • Updates documentation, fixtures, generated snapshots, and tests/coverage to validate the new behavior (including cross-file import-mapping rejection for split targets).

Reviewed changes

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

Show a summary per file
File Description
docs/design.md Documents the direction-projection model and naming/splitting rules for readOnly/writeOnly.
crates/oapi-codegen/tests/generated/server_auth.rs Updates generated doc comment style output for multi-line descriptions.
crates/oapi-codegen/tests/generated/read_write_only.rs Adds generated snapshot demonstrating request/response shape splitting for marked properties.
crates/oapi-codegen/tests/generated/combined_read_write_only.rs Adds combined server/client generated snapshot exercising split models in operations, multipart, client, and server code.
crates/oapi-codegen/tests/generated.rs Registers new generated snapshots and adds behavioral tests for split request/response shapes.
crates/oapi-codegen/tests/fixtures/server_unsupported_xfile_direction_split.yaml Adds fixture for rejecting cross-file $ref into a schema that would split.
crates/oapi-codegen/tests/fixtures/schemas/compose_marked.yaml Adds shared-schema fixture that triggers splitting to validate import-mapping rejection.
crates/oapi-codegen/tests/fixtures/read_write_only.yaml Adds fixture for base direction-splitting behavior (struct, holder, alias, untouched).
crates/oapi-codegen/tests/fixtures/read_write_only_conflict.yaml Adds fixture validating rejection when both marks are set.
crates/oapi-codegen/tests/fixtures/combined_read_write_only.yaml Adds fixture covering direction behavior in a full API (request bodies, responses, multipart).
crates/oapi-codegen/tests/coverage.rs Marks meta.readOnly/meta.writeOnly as supported and adds unsupported conflict + fixture coverage.
crates/oapi-codegen/src/lower/schema.rs Lowers readOnly/writeOnly into per-field Access (including $ref targets) and rejects conflicting marks.
crates/oapi-codegen/src/lower/recurse.rs Updates tests to account for the new Field.access field.
crates/oapi-codegen/src/lower/paths.rs Ensures multipart extractor drops readOnly parts and threads direction access checks into multipart lowering.
crates/oapi-codegen/src/lower/mod.rs Exposes the new direction module and re-exports split_by_direction.
crates/oapi-codegen/src/lower/direction.rs New lowering pass implementing model/service projection and type rewriting for request/response shapes.
crates/oapi-codegen/src/loader.rs Rejects import-mapping references to schemas that would split and adds a same-document scan to detect them.
crates/oapi-codegen/src/lib.rs Integrates direction splitting into the main lowering pipeline (before prune and name checks) and models-only generation.
crates/oapi-codegen/src/ir.rs Adds Direction and Access enums and the Field.access field to the IR.
crates/oapi-codegen/src/emit/usage.rs Exposes direction usage data (direction_usage, adjacency, Usage) needed by the direction pass.
crates/oapi-codegen/src/emit/models.rs Updates tests for the new Field.access field in test fixtures.
crates/oapi-codegen/src/emit/mod.rs Improves doc emission to split multi-line descriptions into multiple /// lines.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread crates/oapi-codegen/src/loader.rs
@dotkas
dotkas marked this pull request as ready for review August 23, 2026 17:15
Copilot AI review requested due to automatic review settings August 23, 2026 17:15

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 22 changed files in this pull request and generated no new comments.

Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

crates/oapi-codegen/src/lower/direction.rs:282

  • This doc comment says project_service “drop[s] the multipart parts a request must not send”, but this function only rewrites types; multipart field dropping happens earlier during lowering (multipart_part_is_sent in lower/paths.rs). Please adjust the comment to avoid misleading future maintainers.
/// Point every API position at the shape of the direction it carries, and drop
/// the multipart parts a request must not send.

crates/oapi-codegen/src/loader.rs:459

  • direction_split_schemas() treats a component schema with schema_data.read_only/write_only set (e.g. a shared primitive schema marked readOnly and referenced via $ref) as if it will be emitted as <Name>Request/<Name>Response. The lowering pass only splits models when a struct field ends up with Access != ReadWrite, so such “schema-level” marks can be used to mark a referencing property without the referenced schema itself being split. As a result, external_schema_name() can reject valid import-mapping references and the error message can describe shapes the models run never emits. Consider aligning direction_split_schemas() with the same “sensitive model” criteria as lower::direction (seed from object properties whose effective Access is not ReadWrite, then close over referrers), so only actually-split schemas are rejected here.
        let ident = crate::naming::to_ident(&chosen, crate::naming::Case::Pascal);
        if direction_split_schemas(&doc).contains(name) {
            let shape = ident.logical();
            return Err(Error::UnsupportedRef {
                reference: reference.to_owned(),

@dotkas
dotkas force-pushed the dotkas/support-readonly-and-writeonly branch from 4d4729c to 0340176 Compare August 23, 2026 17:41
Copilot AI review requested due to automatic review settings August 23, 2026 17:41

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 22 changed files in this pull request and generated 1 comment.

Comment thread crates/oapi-codegen/src/lower/direction.rs
Copilot AI review requested due to automatic review settings August 23, 2026 17:59
@dotkas
dotkas force-pushed the dotkas/support-readonly-and-writeonly branch from 0340176 to 17024b3 Compare August 23, 2026 17:59

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 22 changed files in this pull request and generated 2 comments.

Comment thread crates/oapi-codegen/src/loader.rs
Comment thread crates/oapi-codegen/src/lower/direction.rs Outdated
Copilot AI review requested due to automatic review settings August 23, 2026 18:13

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 22 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings August 23, 2026 18:20
@dotkas
dotkas force-pushed the dotkas/support-readonly-and-writeonly branch from 7c3107e to a1e1ec7 Compare August 23, 2026 18:20

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 22 changed files in this pull request and generated 1 comment.

Comment thread crates/oapi-codegen/src/ir.rs
@dotkas
dotkas merged commit 9633069 into develop Aug 23, 2026
8 checks passed
@dotkas
dotkas deleted the dotkas/support-readonly-and-writeonly branch August 23, 2026 18:41
@alchemax-housekeeper

Copy link
Copy Markdown
Contributor

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

The release is available on GitHub release

Your semantic-release bot 📦🚀

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.

Add support for readonly and writeonly directives

2 participants