#pragma once // ───────────────────────────────────────────────────────────────────────────── // test_fullapi_proxy — universal C++ consumer/proxy. // // Consumes the full `full_api` surface of EITHER provider (test_fullapi_cpp or // test_fullapi_rust) via an INTERFACE dependency (interfaces/full_api.h), and // RE-EXPOSES the exact same surface itself — every call forwards to the bound // provider, every provider event is captured and re-emitted. So the proxy is // itself a drop-in `full_api` provider that delegates to another. // // useProvider(name) selects the runtime target (cross-language: bind to the C++ // or the Rust provider). getLastEvent() returns a short summary of the most // recent forwarded event so a CLI doctest can assert event delivery. // // The bind/call sites live in the .cpp (which includes the generated // logos_sdk.h); this header the generator parses stays free of codegen types. // NO trailing `// comments` on declaration lines (the parser needs a trailing `;`). // ───────────────────────────────────────────────────────────────────────────── #include #include #include #include #include // LogosMap, LogosList, nlohmann::json #include // LogosModuleContext base (gives modules()) #include // StdLogosResult class TestFullapiProxyImpl : public LogosModuleContext { public: TestFullapiProxyImpl() = default; ~TestFullapiProxyImpl() = default; void onContextReady() override; // ── Control ────────────────────────────────────────────────────────────── // Bind the interface to `name` for method forwarding + subscribe to its // events. Returns true. bool useProvider(const std::string& name); // The module name currently bound. std::string currentProvider(); // Short summary (":") of the most recently // forwarded event; empty until one arrives. std::string getLastEvent(); // Round-trip every array type through the bound provider (LP path) and // report the received sizes as a string — a CLI-observable probe of the // provider's array decode, isolated from the Qt/ui-host transport. std::string probeArrays(); // Forward a few methods to the bound provider through the ASYNC client // wrappers (Async), storing each result as its completion fires. // probeAsync() kicks them off and returns immediately; getAsyncProbe() // reports what has arrived. A CLI drives the pair with the daemon event loop // in between (it delivers the completions), exercising the proxy → provider // ASYNC call path (the sync forwards above only cover the blocking path). std::string probeAsync(); std::string getAsyncProbe(); // ── Forwarded full_api surface (same signatures as IFullApi) ───────────── std::string whoAmI(); std::string echoString(const std::string& v); std::vector echoBytes(const std::vector& v); int64_t echoInt(int64_t v); uint64_t echoUint(uint64_t v); double echoDouble(double v); bool echoBool(bool v); nlohmann::json echoAny(const nlohmann::json& v); std::vector echoStringList(const std::vector& v); std::vector echoIntList(const std::vector& v); std::vector echoUintList(const std::vector& v); std::vector echoDoubleList(const std::vector& v); std::vector echoBoolList(const std::vector& v); LogosList echoList(const LogosList& v); LogosMap echoMap(const LogosMap& v); void doVoid(); std::string echoTriple(int64_t i, const std::string& s, const std::vector& b); StdLogosResult makeResult(bool ok); bool fireStringEvent(const std::string& v); bool fireBytesEvent(const std::vector& v); bool fireIntEvent(int64_t v); bool fireUintEvent(uint64_t v); bool fireDoubleEvent(double v); bool fireBoolEvent(bool v); bool fireAnyEvent(const nlohmann::json& v); bool fireStringListEvent(const std::vector& v); bool fireIntListEvent(const std::vector& v); bool fireUintListEvent(const std::vector& v); bool fireDoubleListEvent(const std::vector& v); bool fireBoolListEvent(const std::vector& v); bool fireListEvent(const LogosList& v); bool fireMapEvent(const LogosMap& v); bool fireTripleEvent(int64_t i, const std::string& s, const std::vector& b); // ── Re-emitted events (mirror full_api) ────────────────────────────────── logos_events: void stringEvent(const std::string& v); void bytesEvent(const std::vector& v); void intEvent(int64_t v); void uintEvent(uint64_t v); void doubleEvent(double v); void boolEvent(bool v); void anyEvent(const nlohmann::json& v); void stringListEvent(const std::vector& v); void intListEvent(const std::vector& v); void uintListEvent(const std::vector& v); void doubleListEvent(const std::vector& v); void boolListEvent(const std::vector& v); void listEvent(const LogosList& v); void mapEvent(const LogosMap& v); void tripleEvent(int64_t i, const std::string& s, const std::vector& b); private: void subscribeToTarget(); std::string m_target = "test_fullapi_cpp"; std::string m_lastEvent; // Results collected by probeAsync()'s async completions. The lp async // callbacks fire on the transport's delivery thread, so guard the fields // with a mutex (probeAsync writes, getAsyncProbe reads from another call). std::mutex m_asyncMx; int m_asyncDone = 0; std::vector m_asyncFails; std::string m_asyncWho; };