Skip to content

fix(generator): impl stub one field per line to fix E0063 missing fields#292

Open
casibbald wants to merge 1 commit intomainfrom
feat/impl-stub-full-response-and-decimal-lint
Open

fix(generator): impl stub one field per line to fix E0063 missing fields#292
casibbald wants to merge 1 commit intomainfrom
feat/impl-stub-full-response-and-decimal-lint

Conversation

@casibbald
Copy link
Contributor

@casibbald casibbald commented Jan 31, 2026

  • impl_controller_stub.rs.txt: remove Tera whitespace stripping so each response field is on its own line; all-on-one-line let first // comment hide rest of fields and caused missing-field compile errors
  • Resolve response schema before extract_fields for full Response literal
  • Add decimal/money lint rule in lint_property; tests

Note

Medium Risk
Touches core code generation (impl stubs, Cargo.toml emission) and adds new lint warnings; low blast radius but could change generated output and CI expectations for existing specs.

Overview
Impl stub generation now resolves bare $ref response schemas before extract_fields, ensuring generated Response { ... } literals include all properties and don’t trigger missing-field compile errors. The impl_controller_stub.rs.txt template stops whitespace-stripping around the response field loop so each field renders on its own line (preventing a comment from swallowing subsequent fields).

Project generation now writes a minimal Cargo.toml when neither --version nor a deps config is provided, and when using workspace deps it filters configured dependencies to only those present in [workspace.dependencies]. The linter adds a new warning (money_type_without_decimal_format) for money-like type: number properties missing format: decimal|money, with accompanying tests.

Written by Cursor Bugbot for commit 7fe7fdf. This will update automatically on new commits. Configure here.

Summary by CodeRabbit

  • New Features

    • Added linting checks for monetary and amount-like properties to enforce proper decimal or money format specification with helpful suggestions.
  • Bug Fixes

    • Improved OpenAPI schema reference resolution to ensure complete property definitions are used in response stub generation.
  • Refactor

    • Enhanced dependency management with workspace-aware configuration filtering for improved build flexibility.

✏️ Tip: You can customize this high-level summary in your review settings.

- impl_controller_stub.rs.txt: remove Tera whitespace stripping so each
  response field is on its own line; all-on-one-line let first // comment
  hide rest of fields and caused missing-field compile errors
- Resolve response schema before extract_fields for full Response literal
- Add decimal/money lint rule in lint_property; tests
@coderabbitai
Copy link

coderabbitai bot commented Jan 31, 2026

📝 Walkthrough

Walkthrough

The pull request introduces OpenAPI schema $ref resolution during stub generation to properly handle referenced components, adds linter validation to warn about monetary properties lacking decimal format specifications, improves workspace dependency filtering in Cargo manifest generation, and includes formatting adjustments across templates and tests.

Changes

Cohort / File(s) Summary
OpenAPI Reference Resolution
src/generator/project/generate.rs
Added explicit $ref resolution in stub generation. Loads OpenAPI spec and resolves $ref references in response schemas before extracting fields, ensuring complete property sets are used for code generation.
Monetary Property Validation
src/linter.rs, src/linter/tests.rs
Introduces validation for money-like numeric properties. Detects properties with money/amount-related names lacking decimal or money format, issues warnings with remediation suggestions, and includes test coverage validating the detection and warning behavior.
Workspace Dependency Handling
src/generator/templates.rs
Augments Cargo.toml generation with workspace awareness. Scans for workspace.dependencies and filters config dependencies and conditionals to only include those present in the workspace when use_workspace_deps is enabled.
Minor Refactoring & Formatting
src/generator/schema.rs, templates/impl_controller_stub.rs.txt, tests/generator_version_tests.rs
Formatting adjustments including unused variable prefixing, template whitespace control changes, and test assertion reformatting; no functional behavior modifications.

Sequence Diagram

sequenceDiagram
    participant Gen as Stub Generator
    participant Loader as Route/Spec Loader
    participant Resolver as Reference Resolver
    participant Extractor as Field Extractor

    Gen->>Loader: Load routes
    Gen->>Loader: Load OpenAPI spec
    Loader-->>Gen: Return spec
    
    loop For each route
        Gen->>Resolver: Resolve $ref in response schema
        alt Schema contains $ref
            Resolver->>Resolver: Lookup component definition
            Resolver-->>Gen: Return resolved schema
        else Direct schema
            Resolver-->>Gen: Return schema as-is
        end
        
        Gen->>Extractor: Extract response fields from resolved schema
        Extractor-->>Gen: Return complete field set
        Gen->>Gen: Generate stub code with fields
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 Hop along, dear code now grows,
Refs resolved where schema flows,
Decimals guard our coin so bright,
Workspace deps aligned just right,
Changes bloom in morning light! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and specifically describes the main fix: making impl stub generate one field per line to resolve E0063 missing field compiler errors.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/impl-stub-full-response-and-decimal-lint

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7fe7fdfba8

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines 925 to +928
for (name, spec) in &config.dependencies {
if use_workspace_deps && !workspace_deps.is_empty() && !workspace_deps.contains(name) {
continue;
}

Choose a reason for hiding this comment

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

P2 Badge Keep non-workspace deps instead of silently dropping them

When generating inside a workspace that has [workspace.dependencies], this new filter skips any config dependency not listed there. That silently removes valid per-crate dependencies (e.g., a crates.io version specified in brrtrouter-dependencies.toml), so the generated Cargo.toml can miss crates that the generated code expects and fail to compile. Consider keeping those deps with their explicit spec (or at least surfacing an error) instead of continue-skipping them.

Useful? React with 👍 / 👎.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

for param in &route.parameters {
request_fields.push(parameter_to_field(param));
}
let response_fields = route
Copy link

Choose a reason for hiding this comment

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

Sync path missing $ref resolution for response schema

Medium Severity

The $ref resolution fix for response schemas was only applied to the non-sync path but not to the sync path. When using --sync mode, if the response schema is a bare $ref (like {"$ref": "#/components/schemas/Response"}), extract_fields will return an empty vector because a $ref object has no properties field. This causes synced stubs to lose their response fields.

Additional Locations (1)

Fix in Cursor Fix in Web

deps_config.as_ref(),
Some(&detected_conditional_deps),
)?;
}
Copy link

Choose a reason for hiding this comment

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

Redundant conditional branch adds unnecessary complexity

Low Severity

The new conditional if deps_config.is_none() && version.is_none() creates two code paths that produce the same result. The write_cargo_toml function is just a thin wrapper that calls write_cargo_toml_with_options with default values. Additionally, when this branch executes, use_workspace_deps gets re-computed inside write_cargo_toml even though it was already computed at line 396-397.

Fix in Cursor Fix in Web

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/generator/project/generate.rs`:
- Around line 682-697: The sync branch is still building response_fields from
the raw schema (producing empty fields for $ref); update the sync path to reuse
the already-parsed OpenApiV3Spec (the spec variable created from spec_path) and
the same $ref-resolution logic used for the non-sync branch when constructing
response_fields. Concretely, in the sync branch code that builds response_fields
(the branch handling --sync), replace the raw-schema inspection with the
resolver/path-following logic that uses spec (and any helper used elsewhere to
expand $ref) so $ref-resolved response fields are produced; apply the same
change to the other sync block later as mentioned (the second occurrence
building response_fields).

Comment on lines +682 to +697
// Load spec and routes
let spec_str = spec_path
.to_str()
.ok_or_else(|| anyhow::anyhow!("Invalid UTF-8 in spec path"))?;
let (routes, _slug) = load_spec(spec_str)?;

// Load OpenAPI spec again for $ref resolution when building response fields (ensures full Response in stubs)
let spec: OpenApiV3Spec = if spec_path
.extension()
.map(|e| e == "yaml" || e == "yml")
.unwrap_or(false)
{
serde_yaml::from_str(&std::fs::read_to_string(spec_path)?)?
} else {
serde_json::from_str(&std::fs::read_to_string(spec_path)?)?
};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Sync mode still misses $ref-resolved response fields.

--sync still builds response_fields from the raw response schema, so $ref responses can produce empty fields and keep the E0063 error. Please reuse the new $ref resolution logic for the sync branch as well (around Line 773).

🛠️ Suggested fix for the sync path
-            let response_fields = route
-                .response_schema
-                .as_ref()
-                .map_or(vec![], extract_fields);
+            let response_schema_value: serde_json::Value = route
+                .response_schema
+                .as_ref()
+                .and_then(|v| {
+                    if let Some(ref_path) = v.get("$ref").and_then(|r| r.as_str()) {
+                        resolve_schema_ref(&spec, ref_path)
+                            .and_then(|s| serde_json::to_value(s).ok())
+                    } else {
+                        Some(v.clone())
+                    }
+                })
+                .unwrap_or_default();
+            let response_fields = extract_fields(&response_schema_value);

Also applies to: 825-838

🤖 Prompt for AI Agents
In `@src/generator/project/generate.rs` around lines 682 - 697, The sync branch is
still building response_fields from the raw schema (producing empty fields for
$ref); update the sync path to reuse the already-parsed OpenApiV3Spec (the spec
variable created from spec_path) and the same $ref-resolution logic used for the
non-sync branch when constructing response_fields. Concretely, in the sync
branch code that builds response_fields (the branch handling --sync), replace
the raw-schema inspection with the resolver/path-following logic that uses spec
(and any helper used elsewhere to expand $ref) so $ref-resolved response fields
are produced; apply the same change to the other sync block later as mentioned
(the second occurrence building response_fields).

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