// Copyright (c) 2025 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef MP_PROXY_TYPE_INTERFACE_H #define MP_PROXY_TYPE_INTERFACE_H #include namespace mp { template kj::Own MakeProxyServer(InvokeContext& context, std::shared_ptr impl) { return kj::heap>(std::move(impl), context.connection); } template kj::Own CustomMakeProxyServer(InvokeContext& context, std::shared_ptr&& impl) { return MakeProxyServer(context, std::move(impl)); } template void CustomBuildField(TypeList>, Priority<1>, InvokeContext& invoke_context, Value&& value, Output&& output, typename Decay::Calls* enable = nullptr) { if (value) { using Interface = typename decltype(output.get())::Calls; output.set(CustomMakeProxyServer(invoke_context, std::shared_ptr(value.release()))); } } template void CustomBuildField(TypeList>, Priority<2>, InvokeContext& invoke_context, Value&& value, Output&& output, typename Decay::Calls* enable = nullptr) { if (value) { using Interface = typename decltype(output.get())::Calls; output.set(CustomMakeProxyServer(invoke_context, std::move(value))); } } template void CustomBuildField(TypeList, Priority<1>, InvokeContext& invoke_context, Impl& value, Output&& output, typename decltype(output.get())::Calls* enable = nullptr) { // Disable deleter so proxy server object doesn't attempt to delete the // wrapped implementation when the proxy client is destroyed or // disconnected. using Interface = typename decltype(output.get())::Calls; output.set(CustomMakeProxyServer(invoke_context, std::shared_ptr(&value, [](Impl*){}))); } template std::unique_ptr MakeProxyClient(InvokeContext& context, typename Interface::Client&& client) { return std::make_unique>( std::move(client), &context.connection, /* destroy_connection= */ false); } template std::unique_ptr CustomMakeProxyClient(InvokeContext& context, typename Interface::Client&& client) { return MakeProxyClient(context, kj::mv(client)); } template decltype(auto) CustomReadField(TypeList>, Priority<1>, InvokeContext& invoke_context, Input&& input, ReadDest&& read_dest, typename Decay::Calls* enable = nullptr) { using Interface = typename Decay::Calls; if (input.has()) { return read_dest.construct( CustomMakeProxyClient(invoke_context, std::move(input.get()))); } return read_dest.construct(); } template decltype(auto) CustomReadField(TypeList>, Priority<1>, InvokeContext& invoke_context, Input&& input, ReadDest&& read_dest, typename Decay::Calls* enable = nullptr) { using Interface = typename Decay::Calls; if (input.has()) { return read_dest.construct( CustomMakeProxyClient(invoke_context, std::move(input.get()))); } return read_dest.construct(); } } // namespace mp #endif // MP_PROXY_TYPE_INTERFACE_H