Skip to content

feat: support complex structs in bridge via serde (#21)#30

Open
SAY-5 wants to merge 2 commits intoitisrohit:mainfrom
SAY-5:feat/complex-struct-bridge
Open

feat: support complex structs in bridge via serde (#21)#30
SAY-5 wants to merge 2 commits intoitisrohit:mainfrom
SAY-5:feat/complex-struct-bridge

Conversation

@SAY-5
Copy link
Copy Markdown

@SAY-5 SAY-5 commented Apr 11, 2026

Adds serde-based bridge support for complex Rust structs, letting the TypeScript side work with nested types, collections, and optional fields without manual conversion.

Also fixed UserProfile.id from u64 to u32 to avoid precision loss across the JS bridge (IEEE-754 doubles can't safely represent u64 values above 2^53-1).

Closes #21

Adds end-to-end support for deeply nested Rust structs across the
JNI/FFI bridge, covering all three sub-tasks from the Phase 6 roadmap:

1. Core (Rust): Two new demo commands using #[befu::command] —
   `user.profile.echo` accepts a UserProfile with nested Address,
   GeoCoord, Vec<String>, Vec<f64>, and HashMap<String, Value>;
   `data.aggregate` accepts Vec<DataItem> with Vec<Vec<String>>
   nested tags and returns computed aggregates.

2. Packages (TypeScript): BridgeCommandMap extended with typed
   interfaces (UserProfile, Address, GeoCoord, DataItem, etc.)
   for the new commands, proving arbitrary JSON round-trips
   with full type safety on both sides.

3. Validation: 4 new bridge integration tests verifying:
   - deeply nested JSON round-trip (6 levels deep)
   - Vec of structs with nested arrays
   - missing nested field rejection (coords omitted)
   - empty collection edge case
   Plus 2 Rust unit tests for the compute logic.

All 11 tests pass (was 6, now 11).
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 11, 2026

Walkthrough

Adds two new Serde-backed command handlers and data types to the Rust core, registers them in the command registry, extends TypeScript bridge types for those commands, and adds integration tests exercising nested-struct serialization, aggregation, and error cases.

Changes

Cohort / File(s) Summary
Command Implementation
crates/core/src/demo_commands.rs
Added Serde Serialize/Deserialize structs (GeoCoord, Address, UserProfile, ComputedFields, UserProfileEchoResponse, DataItem, AggregateResponse) and two commands: user_profile_echo (computes tag_count, avg_score) and data_aggregate (computes count, total, average, sorted/deduped categories). Added unit tests for both functions.
Registry Wiring
crates/core/src/lib.rs
Imported demo_commands and registered demo_commands::user_profile_echo and demo_commands::data_aggregate in the command registry initialization via befu_macros::register_commands!.
Bridge Type Definitions
packages/bridge/src/index.ts
Exported TypeScript interfaces mirroring the new Rust structs and extended BridgeCommandMap with 'user.profile.echo' and 'data.aggregate' entries for strongly-typed invocations.
Integration Tests
crates/core/tests/bridge.rs
Added four Phase 6 tests: success round-trip for user.profile.echo (including computed fields), success and empty-input tests for data.aggregate, and a negative test asserting an INVALID_ARGUMENT error when a required nested field (coords) is missing.

Sequence Diagram

sequenceDiagram
    participant Client as TypeScript Client
    participant Bridge as Bridge Layer
    participant Serializer as Serde (JSON)
    participant Handler as Rust Command Handler

    Client->>Bridge: invoke('user.profile.echo', { profile: UserProfile })
    activate Bridge
    Bridge->>Serializer: parse JSON -> UserProfile
    activate Serializer
    Serializer-->>Bridge: UserProfile (nested structs)
    deactivate Serializer
    Bridge->>Handler: call user_profile_echo(profile)
    activate Handler
    Handler->>Handler: compute tag_count & avg_score
    Handler-->>Bridge: UserProfileEchoResponse
    deactivate Handler
    Bridge->>Serializer: serialize response -> JSON
    activate Serializer
    Serializer-->>Bridge: JSON result
    deactivate Serializer
    Bridge-->>Client: { ok: true, result: UserProfileEchoResponse }
    deactivate Bridge
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

  • PR #16: Implements the befu_macros::register_commands! macro and #[command] procedural macros used to register the new command handlers.
  • PR #15: Adds demo command patterns and registry wiring that this change extends with additional demo commands.

Poem

🐰
Hoppy structs hop through JSON lanes,
Nested tags and coords in trains,
Scores and counts all tallied bright,
Categories sorted, duplicates light,
A little rabbit cheers: bytes feel right!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title follows Conventional Commits style with 'feat:' prefix and clearly summarizes the main change: adding support for complex structs in the bridge via serde.
Linked Issues check ✅ Passed The PR fully addresses all requirements from issue #21: extends befu::command macro for serde types, provides TypeScript interfaces in @befu/bridge, and includes comprehensive validation tests demonstrating complex nested structs and arrays.
Out of Scope Changes check ✅ Passed All changes are directly scoped to issue #21 requirements: new demo commands, TypeScript type definitions, and validation tests for complex struct bridging. A follow-up commit adjusting UserProfile.id (u64→u32) is also justified for JavaScript precision safety.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description check ✅ Passed The PR description clearly relates to the changeset, explaining serde-based bridge support for complex structs and a u32/u64 fix for precision loss.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/core/src/demo_commands.rs`:
- Around line 35-37: The UserProfile.id is a u64 which will lose precision when
mapped to a JS number; update serialization so IDs are sent as strings and
adjust the bridge typing accordingly: annotate UserProfile.id (the id field in
the UserProfile struct) with a serde serializer that emits/consumes a string
(e.g., #[serde(with = "serde_with::rust::display_fromstr")] or
#[serde(serialize_with = "...", deserialize_with = "...")]) and then change the
TypeScript interface in packages/bridge/src/index.ts to use id: string so
round-trips remain lossless. Ensure the chosen serde helper handles both
serialize and deserialize for u64-to-string conversion.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 9dc342db-31ce-43b0-88f5-461ba4d2d680

📥 Commits

Reviewing files that changed from the base of the PR and between 5febd64 and 33905ec.

📒 Files selected for processing (4)
  • crates/core/src/demo_commands.rs
  • crates/core/src/lib.rs
  • crates/core/tests/bridge.rs
  • packages/bridge/src/index.ts

Comment thread crates/core/src/demo_commands.rs
…loss

JavaScript numbers are IEEE-754 doubles, safe only up to 2^53-1.
u64 values above this threshold lose precision across the bridge.
u32 (max 4,294,967,295) is safely representable.

Addresses review feedback on itisrohit#30.
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.

[HELP WANTED] Support Complex Structs in Bridge (JSON/Serde integration)

1 participant