Skip to content

Conversation

@remybar
Copy link
Collaborator

@remybar remybar commented Sep 9, 2025

Description

Whatever if a model is a legacy one or a DojoStore one, model keys must always be serialized with Serde.

Tests

  • Yes
  • No, because they aren't needed
  • No, because I need help

Added to documentation?

  • README.md
  • Dojo Book
  • No documentation needed

Checklist

  • I've formatted my code (scripts/rust_fmt.sh, scripts/cairo_fmt.sh)
  • I've linted my code (scripts/clippy.sh, scripts/docs.sh)
  • I've commented my code
  • I've requested a review after addressing the comments

Summary by CodeRabbit

  • New Features
    • Added support for models using enum keys.
  • Bug Fixes
    • Ensured model keys are always serialized with the legacy format for consistent compatibility across storage modes.
    • Improved error handling when accessing non-struct model layouts by failing fast with a clear panic.
  • Chores
    • Enhanced test artifact rebuild workflow: reordered formatting after world binding updates, added additional artifact builds, automatic Katana provisioning, and test database generation/extraction for more reliable local testing.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 9, 2025

ohayo, sensei!

Walkthrough

Adds enum-keyed test models and tests, updates model attribute macro to serialize keys per-member with legacy semantics, adjusts a layout utility to panic instead of returning None in a branch, and expands the test artifact rebuild script with formatting reordering, Katana provisioning, and test DB generation.

Changes

Cohort / File(s) Summary
Core tests: enum-keyed models
crates/dojo/core-tests/src/tests/model/model.cairo
Introduces EnumKey, two test models (legacy and DojoStore) with enum keys, registers them in namespace, and adds tests covering (de)serialization and default initialization semantics.
Model macro: per-member (de)serialization
crates/dojo/macros/src/attributes/model.rs
Replaces bulk serialize/deserialize with per-member handling; forces keys to legacy serialization; values respect model.use_legacy_storage; updates corresponding deserialization paths.
Layout utility behavior
crates/dojo/core/src/utils/layout.cairo
Removes Option::None return after panic in non-struct branch of find_model_field_layout, retaining only panic.
Test artifacts & tooling
scripts/rebuild_test_artifacts.sh
Reorders formatting to post-abigen; adds Katana provisioning, test DB generation and extraction; expands build/test steps (including release variant).

Sequence Diagram(s)

sequenceDiagram
  participant Dev as Developer
  participant Macro as #[dojo::model] Macro
  participant DF as DojoFormatter
  Dev->>Macro: Expand model with members
  loop For each member
    alt Member is #[key]
      Macro->>DF: serialize_member_ty(db, member, use_legacy=true, is_key=true)
      Macro->>Macro: push to serialized_keys
      Macro->>DF: deserialize_member_ty(db, member, use_legacy=true, source="keys")
    else Non-key member (value)
      Macro->>DF: serialize_member_ty(db, member, use_legacy=model.use_legacy_storage, is_key=false)
      Macro->>Macro: push to serialized_values
      Macro->>DF: deserialize_member_ty(db, member, use_legacy=model.use_legacy_storage, source="values")
    end
  end
  Note over Macro: Keys always use legacy semantics
Loading
sequenceDiagram
  participant C as Caller
  participant L as find_model_field_layout
  C->>L: Query field layout for model
  alt Model is struct
    L-->>C: Some(field layout)
  else Not a struct
    L--xC: panic("Model layout is not a struct")
  end
  Note over L: Removed None return path after panic
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

contributor

Suggested reviewers

  • glihm
  • kariy

Pre-merge checks (3 passed)

✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The title accurately and concisely summarizes the primary change of always serializing model keys with Serde across both legacy and DojoStore models, follows conventional commit style, and is directly related to the changeset.
Description Check ✅ Passed The description clearly states the intent to ensure model keys are serialized with Serde regardless of model type, which aligns directly with the changeset and is not off-topic.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-serialized_enum_key

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

Copy link
Contributor

@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: 0

🧹 Nitpick comments (5)
crates/dojo/core/src/utils/layout.cairo (1)

30-30: ohayo, sensei — Docstring now lies; function panics instead of returning None.

The else-branch is now a hard panic, so the “None otherwise” contract is no longer true. Please align the docs to avoid misleading callers.

Proposed doc tweak (outside selected lines):

-/// Some(Layout) if the field layout has been found, None otherwise.
+/// Returns Some(Layout) if the field layout has been found.
+/// Panics if `model_layout` is not a `Layout::Struct` (this should be unreachable for models).
scripts/rebuild_test_artifacts.sh (1)

35-38: Make DB generation more robust.

Consider guarding these steps with set -euo pipefail (proposed above) so failures propagate, and optionally echo where the DB is written for easier debugging.

crates/dojo/macros/src/attributes/model.rs (1)

111-118: Optional: reduce the double-walk of members.

You iterate struct_ast.members(...) for (de)serialization and later re-iterate parsed members to build metadata. You could consolidate into one pass that accumulates both codegen snippets and metadata to shave complexity, but not required.

Also applies to: 126-132, 133-139

crates/dojo/core-tests/src/tests/model/model.cairo (2)

724-780: Strong coverage for legacy enum-key path; tiny typo nit.

Assertions match expected Serde encodings and legacy defaults. Please fix “unitialized” → “uninitialized”.

Patch within this hunk:

-    // read unitialized model, write and read back
+    // read uninitialized model, write and read back
@@
-        "LegacyModelWithEnumKey: read unitialized model failed",
+        "LegacyModelWithEnumKey: read uninitialized model failed",

783-840: DojoStore enum-key path covered; repeat the typo fix.

Encodings and defaults look correct for DojoStore. Please fix the same typo here.

Patch within this hunk:

-    // read unitialized model, write and read back
+    // read uninitialized model, write and read back
@@
-        "DojoStoreModelWithEnumKey: read unitialized model failed",
+        "DojoStoreModelWithEnumKey: read uninitialized model failed",
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 15e2963 and 7f92791.

⛔ Files ignored due to path filters (1)
  • spawn-and-move-db.tar.gz is excluded by !**/*.gz
📒 Files selected for processing (4)
  • crates/dojo/core-tests/src/tests/model/model.cairo (3 hunks)
  • crates/dojo/core/src/utils/layout.cairo (1 hunks)
  • crates/dojo/macros/src/attributes/model.rs (1 hunks)
  • scripts/rebuild_test_artifacts.sh (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
crates/dojo/macros/src/attributes/model.rs (1)
crates/dojo/macros/src/helpers/formatter.rs (2)
  • serialize_member_ty (22-30)
  • deserialize_member_ty (45-58)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: fmt
🔇 Additional comments (10)
scripts/rebuild_test_artifacts.sh (3)

15-18: Formatting reordering LGTM.

Running formatters right after abigen is sensible and harmless.


21-24: Good: broader artifact rebuild coverage.

Adding the release profile and core-tests invocation improves fidelity.


25-33: Harden Katana bootstrap and fail fast

ohayo sensei, apply these changes and double-check runner behavior:

  • Within the existing hunk, replace cp with:
    -    cp "$(command -v katana)" /tmp/katana
    +    install -m0755 "$(command -v katana)" /tmp/katana
  • At the top of scripts/rebuild_test_artifacts.sh, add:
    +set -euo pipefail
  • Verify that xtask/generate-test-db (via KatanaRunner) actually invokes /tmp/katana—e.g. prepend /tmp to $PATH or set KATANA_RUNNER_BIN=/tmp/katana before running.
crates/dojo/macros/src/attributes/model.rs (3)

111-118: ohayo, sensei — Forcing Serde for keys is correct and matches the PR goal.

This ensures stable key encoding across legacy and DojoStore. Looks good.


119-125: Serde-based key deserialization LGTM.

Using the "keys" input and Serde here aligns with the serialization path.


126-132: Values follow storage semantics — clean separation.

Nice split: values use model.use_legacy_storage while keys stay Serde.

Also applies to: 133-139

crates/dojo/core-tests/src/tests/model/model.cairo (4)

109-116: ohayo, sensei — EnumKey definition LGTM.

Derives (including Default and DojoStore) are appropriate for exercising both storage modes.


117-128: LegacyModelWithEnumKey test model LGTM.

Covers enum key + mixed value shapes under legacy semantics.


129-140: DojoStoreModelWithEnumKey test model LGTM.

Validates the key/value split across DojoStore semantics.


222-224: Namespace registration LGTM.

Models are properly added to the test world resources.

Copy link
Collaborator

@glihm glihm left a comment

Choose a reason for hiding this comment

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

Thank you @remybar for the quick fix on that and the correct formatting on the way. 🫡

@glihm glihm merged commit d9725b1 into main Sep 9, 2025
10 checks passed
@glihm glihm deleted the fix-serialized_enum_key branch September 9, 2025 21:04
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.

3 participants