Files
logos-cpp-sdk/cpp-generator
Dario Gabriel LipicarandClaude Opus 5 22bc6cf9b0 Merge origin/master into feat/async-result-and-sync-timeout
Four PRs land on the same emitter (legacy/generator_lib.cpp); this merge keeps
all four, and closes a gap the combination opens.

generator_lib.cpp, sync body — BOTH sides were needed, not one:
  s << "}, timeout, &_err);\n";                                  (#132: the caller's
  s << "    if (_err.ok()) logosDispatchRejection(_result, _err);\n";  deadline)
                                                                 (#129: the rejection fold)
Master emitted `Timeout()` there only because it had no deadline to forward.

generator_lib.cpp, async emission — kept HEAD's emitAsyncParams/emitAsyncArgs/
asyncDecodeExpr lambdas (they let ONE body emit both `<name>Async` and
`<name>AsyncResult` without the two drifting apart) and carried master's
rejection handling into them, routed by what each surface can actually report:

  * `<name>Async`       — callback is std::function<void(T)>: no error slot, so
                          master's qWarning is kept verbatim. Surface unchanged.
  * `<name>AsyncResult` — callback is std::function<void(AsyncResult<T>)>, which
                          DOES have one, so the rejection is folded into
                          `_r.error` before the value is decoded, exactly as the
                          sync path folds it into the caller's CallError.

That last point is the merge's substance rather than a mechanical resolution.
#129 could only warn on the async path because no async callback carried an
error; #132 added one. Leaving `<name>AsyncResult` on the qWarning path would
have made it answer ok() for a rejected call — the precise defect #129 fixed,
reintroduced on the surface #132 added.

tests/generator/CMakeLists.txt: add/add, both test files belong.

Added AsyncResult.RejectionIsFoldedIntoTheAsyncResultError and
AsyncResult.ThePlainAsyncEntryPointStillOnlyWarns to pin the split above.

Verified by running, not by reading emitted text: the merged generator's
consumer wrapper for the real full_api contract, compiled verbatim against the
generated cdylib provider glue for the same contract and driven through its own
logos_module_dispatch (only the socket hop stubbed). The provider really refuses
echoUintList([1,-1,3]) with
{"code":"dispatch_failed","message":"expected unsigned integer at arg0[1], got
number","origin":"test_fullapi_cpp"}. 26/26 checks pass. Controls: the same
harness on the pre-merge branch tip fails 8 (every rejection check) and passes
every #132 check; on master it does not compile (no AsyncResult, no sync
Timeout). Optional spellings emit byte-identical code post-merge and DIFFER
pre-merge, with qt-vs-lp as the non-vacuity control. nix build .#tests: 265/265.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 10:04:19 -03:00
..