Skip to content

feat(ffi-wasi): convert to JSON-RPC 2.0 protocol#352

Merged
robcohen merged 3 commits intomainfrom
feature/ffi-jsonrpc
Feb 14, 2026
Merged

feat(ffi-wasi): convert to JSON-RPC 2.0 protocol#352
robcohen merged 3 commits intomainfrom
feature/ffi-jsonrpc

Conversation

@robcohen
Copy link
Copy Markdown
Member

Summary

  • Replace CLI-style stdin/stdout interface with JSON-RPC 2.0 protocol
  • Add jsonrpc module with request/response handling and method router
  • Implement proper clamp logic with balance sheet summarization and P&L closing
  • Add OpenRPC specification and README documentation

JSON-RPC Methods

Method Description
ledger.load Parse source code
ledger.loadFile Load file with includes
ledger.validate Validate source
query.execute Execute BQL query
entry.clamp Filter with opening balances
entry.filter Simple date filtering
entry.create Create single entry
entry.createBatch Create multiple entries
format.source Format source code
format.entry Format single entry
format.entries Format multiple entries
util.version Get version info
util.types Get type constants
util.isEncrypted Check if file is encrypted
util.getAccountType Get account type

Test plan

  • rustfmt passes
  • clippy passes (no warnings)
  • All tests pass
  • Pre-commit hooks pass

🤖 Generated with Claude Code

Replace CLI-style stdin/stdout interface with JSON-RPC 2.0:

- Add jsonrpc module with request/response handling and router
- Implement JSON-RPC methods:
  - ledger.load, ledger.loadFile, ledger.validate
  - query.execute
  - entry.clamp, entry.filter, entry.create, entry.createBatch
  - format.source, format.entry, format.entries
  - util.version, util.types, util.isEncrypted, util.getAccountType
- Implement proper clamp logic with:
  - Balance sheet account summarization
  - Income/expense closing to Equity:Earnings:Previous
  - Price tracking for entries before date range
- Add OpenRPC specification (openrpc.json)
- Add README with API documentation

This enables language-agnostic integration via JSON-RPC over stdin/stdout.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov bot commented Feb 14, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Feb 14, 2026

📊 Benchmark Results

Tool Time Memory
rustledger 44.1ms ± 1.1ms 22.6 MB
beancount 891.9ms ± 4.8ms 50.1 MB
Comparison 20.2x faster 2.2x less

vs main branch (2026-02-14)

Metric main this PR Change
Time 57ms 44.1ms -22.6% 🟢
10K transactions · 5 runs, 2 warmup · hyperfine
What do these numbers mean?
  • Time: Wall-clock time to parse and validate the ledger (± std dev)
  • Memory: Peak resident set size (RSS)
  • vs main: Compared to latest nightly benchmark on main branch

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Feb 14, 2026

✅ Compatibility Test Results

Metric Result
Check Compatibility 100%
BQL Compatibility 100%
Full AST Match 99%
Total Files 763
What's tested
  • Check: Exit codes and error counts match bean-check
  • BQL: Query results match bean-query
  • Files: ~800 test files downloaded from 10+ beancount repositories

Full results available in workflow artifacts

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR migrates the rustledger-ffi-wasi WASI module from a CLI-style stdin/stdout command interface to a JSON-RPC 2.0 protocol, adding a router-based method dispatch layer plus an OpenRPC spec and README for client integration.

Changes:

  • Replaced CLI command parsing in main.rs with JSON-RPC request processing (jsonrpc::process_stdin).
  • Added JSON-RPC request/response/error types and a method router implementing ledger/query/format/entry/util methods.
  • Added OpenRPC spec (openrpc.json) and crate-level README documenting the JSON-RPC API.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
crates/rustledger-ffi-wasi/src/main.rs Switch entrypoint to JSON-RPC stdin processing and update module docs.
crates/rustledger-ffi-wasi/src/jsonrpc/mod.rs Implement stdin request parsing, routing, and response output.
crates/rustledger-ffi-wasi/src/jsonrpc/request.rs Define JSON-RPC request + params structs and batch parsing.
crates/rustledger-ffi-wasi/src/jsonrpc/response.rs Define JSON-RPC response and per-method result payloads.
crates/rustledger-ffi-wasi/src/jsonrpc/error.rs Define JSON-RPC error codes and error object structure.
crates/rustledger-ffi-wasi/src/jsonrpc/router.rs Implement JSON-RPC method dispatch and handlers for all exposed methods.
crates/rustledger-ffi-wasi/src/commands/clamp.rs Refactor clamp/filter logic into reusable functions for JSON-RPC methods.
crates/rustledger-ffi-wasi/src/commands/query.rs Refactor query execution into a pure function returning QueryOutput.
crates/rustledger-ffi-wasi/src/commands/load.rs Keep LoadFullOutput type for ledger.loadFile response.
crates/rustledger-ffi-wasi/src/commands/util.rs Retain util types (TypesOutput, MissingSentinel) used by router.
crates/rustledger-ffi-wasi/src/commands/mod.rs Narrow commands module to types/helpers used by JSON-RPC.
crates/rustledger-ffi-wasi/src/types/input.rs Add Debug derives for JSON-RPC param deserialization debugging.
crates/rustledger-ffi-wasi/src/types/output.rs Remove legacy CLI output types no longer used (e.g., VersionOutput).
crates/rustledger-ffi-wasi/src/types/mod.rs Stop re-exporting removed legacy output types.
crates/rustledger-ffi-wasi/openrpc.json Add OpenRPC definition for the JSON-RPC surface area.
crates/rustledger-ffi-wasi/README.md Add usage and method documentation for the new JSON-RPC API.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/rustledger-ffi-wasi/src/jsonrpc/router.rs Outdated
Comment thread crates/rustledger-ffi-wasi/src/jsonrpc/router.rs Outdated
Comment thread crates/rustledger-ffi-wasi/src/commands/clamp.rs Outdated
Comment thread crates/rustledger-ffi-wasi/src/jsonrpc/request.rs Outdated
Comment thread crates/rustledger-ffi-wasi/openrpc.json
Comment thread crates/rustledger-ffi-wasi/src/jsonrpc/router.rs
Comment thread crates/rustledger-ffi-wasi/src/commands/clamp.rs Outdated
Comment thread crates/rustledger-ffi-wasi/src/commands/clamp.rs Outdated
Comment thread crates/rustledger-ffi-wasi/src/commands/clamp.rs Outdated
Comment thread crates/rustledger-ffi-wasi/openrpc.json Outdated
@mergify
Copy link
Copy Markdown
Contributor

mergify bot commented Feb 14, 2026

🧪 CI Insights

Here's what we observed from your CI run for 4cf86a7.

🟢 All jobs passed!

But CI Insights is watching 👀

robcohen and others added 2 commits February 14, 2026 13:19
Fixes from Copilot code review:
- Fix booking_methods list: remove REDUCE, add STRICT_WITH_SIZE
- Fix format.entries: use concat() instead of join("\n") to avoid extra newlines
- Fix clamp sort stability: add deterministic tiebreakers (type priority, hash)
- Fix batch parsing: parse each element individually per JSON-RPC 2.0 spec
- Fix OpenRPC columns schema: use ColumnInfo objects instead of strings
- Fix cost parsing: fall back to Position::simple for invalid costs
- Fix price tracking: use >= for same-day prices (last wins)
- Fix filter_entries: drop invalid dates consistently with clamp_entries
- Fix OpenRPC TypesOutput: add missing MissingSentinel field
- Fix clippy warnings: const fn, collapsible if, format strings, semicolons

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Per JSON-RPC 2.0 spec, invalid elements in a batch should return
individual error responses rather than failing the entire batch.

Changes:
- Add BatchElement enum to represent valid/invalid request elements
- Parse batch elements individually, preserving IDs for error responses
- Mark entry.clamp date params as required in OpenRPC spec
- Add 12 unit tests for clamp/filter functionality
- Add integration tests for batch error handling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@robcohen robcohen enabled auto-merge February 14, 2026 19:49
@robcohen robcohen added this pull request to the merge queue Feb 14, 2026
Merged via the queue into main with commit 97d77c5 Feb 14, 2026
26 of 27 checks passed
@robcohen robcohen deleted the feature/ffi-jsonrpc branch February 14, 2026 20:03
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.

2 participants