Generator: emit OpenRPC info.title without colon (openrpc_client! macro rejects it) #91

Closed
opened 2026-05-20 09:46:21 +00:00 by timur · 1 comment
Owner

Problem

#82 landed per-domain openrpc.json files with info.title = "<service>:<domain>" (e.g. "LogicService:logic"). But the hero_rpc_derive::openrpc_client! macro derives Rust identifiers from info.title and rejects colons.

Found by the hero_logic#46 agent during the template-pattern migration — they patched the title in a build.rs post-process step to make the macro accept it. That hack is what this issue removes.

What to do

Pick one in a comment, then implement:

  • (A) Change the per-domain title format to something the macro accepts — e.g. "<service> - <domain>" (space + dash) or "<service>_<domain>" (underscore).
  • (B) Make openrpc_client! sanitise non-identifier characters when deriving Rust idents (drop colons, replace with _, etc.).

My lean: (A). Cleaner: the spec title is metadata, not an identifier. Forcing it to be Rust-ident-shaped works against its primary purpose (human-readable description). Tweaking the formatting is one-line.

Affected callers

  • The macro in hero_rpc/crates/derive/.
  • The emitter at crates/generator/src/generate/openrpc.rs (post-#82).
  • Any service whose build.rs currently hand-patches the title (hero_logic does; verify others).

Acceptance

  • hero_logic (and any other consumer) can drop the build.rs title-patching step.
  • openrpc_client! macro consumes the emitted docs/<domain>/openrpc.json directly.
  • recipe_server + hero_service regenerate clean.
## Problem [#82](https://forge.ourworld.tf/lhumina_code/hero_rpc/issues/82) landed per-domain `openrpc.json` files with `info.title = "<service>:<domain>"` (e.g. `"LogicService:logic"`). But the `hero_rpc_derive::openrpc_client!` macro derives Rust identifiers from `info.title` and rejects colons. Found by the [hero_logic#46](https://forge.ourworld.tf/lhumina_code/hero_logic/pulls/46) agent during the template-pattern migration — they patched the title in a `build.rs` post-process step to make the macro accept it. That hack is what this issue removes. ## What to do Pick one in a comment, then implement: - **(A)** Change the per-domain title format to something the macro accepts — e.g. `"<service> - <domain>"` (space + dash) or `"<service>_<domain>"` (underscore). - **(B)** Make `openrpc_client!` sanitise non-identifier characters when deriving Rust idents (drop colons, replace with `_`, etc.). My lean: **(A)**. Cleaner: the spec title is metadata, not an identifier. Forcing it to be Rust-ident-shaped works against its primary purpose (human-readable description). Tweaking the formatting is one-line. ## Affected callers - The macro in `hero_rpc/crates/derive/`. - The emitter at `crates/generator/src/generate/openrpc.rs` (post-#82). - Any service whose `build.rs` currently hand-patches the title (hero_logic does; verify others). ## Acceptance - `hero_logic` (and any other consumer) can drop the `build.rs` title-patching step. - `openrpc_client!` macro consumes the emitted `docs/<domain>/openrpc.json` directly. - `recipe_server` + `hero_service` regenerate clean. ## Related - Discovery: [hero_logic#46 PR body](https://forge.ourworld.tf/lhumina_code/hero_logic/pulls/46) item 1 - Predecessor that introduced the colon format: [#82](https://forge.ourworld.tf/lhumina_code/hero_rpc/issues/82)
Author
Owner

Implementation pushed on branch issue-91-92-93-generator-fixes. Bundled with the other two generator fixes from the same root (the hero_logic#46 build.rs post-process patches).

  • #91 title format is now <service> - <domain> (space-dash-space). Aggregate strip logic updated to match.
  • #92 emits servers[] from service.toml [[binaries.sockets]] with protocol = "openrpc", URL shape unix://${HERO_SOCKET_DIR}/<path> so openrpc_client!::connect() resolves via resolve_socket_path_with_override. Per-domain narrows by binary name suffix _<domain>; aggregate keeps the union.
  • #93 generate_server_lib_rs discovers hand-written *.rs / <dir>/mod.rs modules carrying //! @server-feature: and emits pub mod lines for them. Marker-required (server crates carry internal helpers; SDK-style discover-everything would over-expose).

Verified via example/recipe_server regen + cargo build --workspace clean + cargo test -p hero_rpc_generator --lib (131 passed).

Implementation pushed on branch [issue-91-92-93-generator-fixes](https://forge.ourworld.tf/lhumina_code/hero_rpc/src/branch/issue-91-92-93-generator-fixes). Bundled with the other two generator fixes from the same root (the hero_logic#46 build.rs post-process patches). - **#91** title format is now `<service> - <domain>` (space-dash-space). Aggregate strip logic updated to match. - **#92** emits `servers[]` from `service.toml` `[[binaries.sockets]]` with `protocol = "openrpc"`, URL shape `unix://${HERO_SOCKET_DIR}/<path>` so `openrpc_client!::connect()` resolves via `resolve_socket_path_with_override`. Per-domain narrows by binary name suffix `_<domain>`; aggregate keeps the union. - **#93** `generate_server_lib_rs` discovers hand-written `*.rs` / `<dir>/mod.rs` modules carrying `//! @server-feature:` and emits `pub mod` lines for them. Marker-required (server crates carry internal helpers; SDK-style discover-everything would over-expose). Verified via `example/recipe_server` regen + `cargo build --workspace` clean + `cargo test -p hero_rpc_generator --lib` (131 passed).
timur closed this issue 2026-05-20 11:57:32 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_rpc#91
No description provided.