feat: support complex structs in bridge via serde (#21)#30
feat: support complex structs in bridge via serde (#21)#30SAY-5 wants to merge 2 commits intoitisrohit:mainfrom
Conversation
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).
WalkthroughAdds 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
Sequence DiagramsequenceDiagram
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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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
📒 Files selected for processing (4)
crates/core/src/demo_commands.rscrates/core/src/lib.rscrates/core/tests/bridge.rspackages/bridge/src/index.ts
…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.
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.idfromu64tou32to avoid precision loss across the JS bridge (IEEE-754 doubles can't safely represent u64 values above 2^53-1).Closes #21