21#ifndef KICAD_API_HANDLER_H
22#define KICAD_API_HANDLER_H
27#include <fmt/format.h>
28#include <tl/expected.hpp>
33#include <google/protobuf/message.h>
36#include <api/common/envelope.pb.h>
41using kiapi::common::ApiRequest, kiapi::common::ApiResponse;
42using kiapi::common::ApiResponseStatus, kiapi::common::ApiStatusCode;
44typedef tl::expected<ApiResponse, ApiResponseStatus>
API_RESULT;
50template <
typename RequestMessageType>
97 typedef std::function<HANDLER_RESULT<ApiResponse>( ApiRequest& )>
REQUEST_HANDLER;
113 template <
class RequestType,
class ResponseType,
class HandlerType>
117 std::string typeName { RequestType().GetTypeName() };
119 wxASSERT_MSG( !
m_handlers.contains( typeName ),
120 wxString::Format(
"Duplicate API handler for type %s", typeName ) );
123 [
this, aHandler]( ApiRequest& aRequest ) ->
API_RESULT
126 ApiResponse envelope;
131 ctx.
ClientName = aRequest.header().client_name();
134 std::invoke( aHandler,
static_cast<HandlerType*
>(
this ), ctx );
136 if( response.has_value() )
138 envelope.mutable_status()->set_status( ApiStatusCode::AS_OK );
139 envelope.mutable_message()->PackFrom( *response );
144 return tl::unexpected( response.error() );
160 template<
typename MessageType>
161 bool tryUnpack( ApiRequest& aRequest, ApiResponse& aReply, MessageType& aDest )
163 if( !aRequest.message().UnpackTo( &aDest ) )
165 std::string msg = fmt::format(
"could not unpack message of type {} from request",
166 aDest.GetTypeName() );
167 aReply.mutable_status()->set_status( ApiStatusCode::AS_BAD_REQUEST );
168 aReply.mutable_status()->set_error_message( msg );
tl::expected< ApiResponse, ApiResponseStatus > API_RESULT
tl::expected< T, ApiResponseStatus > HANDLER_RESULT
static const wxString m_defaultCommitMessage
KICAD_API_SERVER * m_apiServer
virtual void onNetSettingsChanged()
Called on all registered handlers after project net settings (netclasses or netclass assignments) hav...
std::map< std::string, REQUEST_HANDLER > m_handlers
Maps type name (without the URL prefix) to a handler method.
KICAD_API_SERVER * apiServer() const
void registerHandler(HANDLER_RESULT< ResponseType >(HandlerType::*aHandler)(const HANDLER_CONTEXT< RequestType > &))
Registers an API command handler for the given message types.
void requestNetSettingsNotification()
bool clearNetSettingsNotification()
Returns true if the notification had been requested at the time of the call.
bool tryUnpack(ApiRequest &aRequest, ApiResponse &aReply, MessageType &aDest)
std::function< HANDLER_RESULT< ApiResponse >(ApiRequest &)> REQUEST_HANDLER
A handler for outer messages (envelopes) that will unpack to inner messages and call a specific handl...
void setApiServer(KICAD_API_SERVER *aServer)
Set by KICAD_API_SERVER::RegisterHandler; null when the handler is not registered.
Handle(KICAD3D_INFO) KICAD3D_INFO
RequestMessageType Request