cpp-msgpack-rpc 0.2.0
An RPC library implementing MessagePack RPC.
Loading...
Searching...
No Matches
functional_method.h
Go to the documentation of this file.
1/*
2 * Copyright 2023 MusicScience37 (Kenta Kabashima)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
20#pragma once
21
22#include <exception>
23#include <memory>
24#include <tuple>
25#include <type_traits>
26#include <utility>
27
28#include <msgpack.hpp>
29
40
42
49template <typename Signature, typename Function, typename /*for SFINAE*/ = void>
51
59template <typename Function, typename Result, typename... Parameters>
60class FunctionalMethod<Result(Parameters...), Function,
61 std::enable_if_t<!std::is_same_v<Result, void>>>
62 final : public IMethod {
63public:
72 template <typename InputFunction>
73 FunctionalMethod(messages::MethodName name, InputFunction&& function,
74 std::shared_ptr<logging::Logger> logger)
75 : name_(std::move(name)),
76 function_(std::forward<InputFunction>(function)),
77 logger_(std::move(logger)) {}
78
84 [[nodiscard]] messages::MethodNameView name() const noexcept override {
85 return name_;
86 }
87
95 const messages::ParsedRequest& request) override {
96 try {
98 request.id(),
100 request.parameters().as<std::decay_t<Parameters>...>()));
101 } catch (const MethodException& exception) {
103 request.id(), exception.object());
104 }
105 }
106
112 void notify(const messages::ParsedNotification& notification) override {
113 try {
114 std::apply(function_,
115 notification.parameters().as<std::decay_t<Parameters>...>());
116 } catch (const MethodException& e) {
118 "Method {} threw an exception with a custom object: {}", name_,
120 } catch (const std::exception& e) {
122 logger_, "Method {} threw an exception: {}", name_, e.what());
123 }
124 }
125
126private:
136 template <typename ParameterTuple>
137 decltype(auto) invoke_with_tuple(ParameterTuple&& parameter_tuple) {
138 try {
139 return std::apply(
140 function_, std::forward<ParameterTuple>(parameter_tuple));
141 } catch (const MethodException& e) {
143 "Method {} threw an exception with a custom object: {}", name_,
145 throw;
146 } catch (const std::exception& e) {
148 logger_, "Method {} threw an exception: {}", name_, e.what());
149 throw MethodException(e.what());
150 }
151 }
152
155
157 std::decay_t<Function> function_;
158
160 std::shared_ptr<logging::Logger> logger_;
161};
162
169template <typename Function, typename... Parameters>
170class FunctionalMethod<void(Parameters...), Function> final : public IMethod {
171public:
180 template <typename InputFunction>
182 std::shared_ptr<logging::Logger> logger)
183 : name_(name),
184 function_(std::forward<InputFunction>(function)),
185 logger_(std::move(logger)) {}
186
192 [[nodiscard]] messages::MethodNameView name() const noexcept override {
193 return name_;
194 }
195
203 const messages::ParsedRequest& request) override {
204 try {
205 std::apply(function_,
206 request.parameters().as<std::decay_t<Parameters>...>());
207 } catch (const MethodException& e) {
209 "Method {} threw an exception with a custom object: {}", name_,
212 request.id(), e.object());
213 } catch (const std::exception& e) {
215 logger_, "Method {} threw an exception: {}", name_, e.what());
217 request.id(), e.what());
218 }
220 request.id(), msgpack::type::nil_t());
221 }
222
228 void notify(const messages::ParsedNotification& notification) override {
229 try {
230 std::apply(function_,
231 notification.parameters().as<std::decay_t<Parameters>...>());
232 } catch (const MethodException& e) {
234 "Method {} threw an exception with a custom object: {}", name_,
236 } catch (const std::exception& e) {
238 logger_, "Method {} threw an exception: {}", name_, e.what());
239 }
240 }
241
242private:
245
247 std::decay_t<Function> function_;
248
250 std::shared_ptr<logging::Logger> logger_;
251};
252
263template <typename Signature, typename Function>
264[[nodiscard]] inline std::unique_ptr<FunctionalMethod<Signature, Function>>
266 // NOLINTNEXTLINE(performance-unnecessary-value-param) : false positive
267 messages::MethodName name, Function&& function,
268 std::shared_ptr<logging::Logger> logger) {
269 return std::make_unique<
271 std::move(name), std::forward<Function>(function), std::move(logger));
272}
273
274} // namespace msgpack_rpc::methods
static SerializedMessage serialize_error_response(MessageID request_id, const T &error)
Serialize an error response.
static SerializedMessage serialize_successful_response(MessageID request_id, const T &result)
Serialize a successful response.
Class of method names.
Definition method_name.h:35
const ParsedParameters & parameters() const noexcept
Get the parameters.
std::tuple< Parameters... > as() const
Get parameters as given types.
const ParsedParameters & parameters() const noexcept
Get the parameters.
MessageID id() const noexcept
Get the message ID.
Class of serialized message data.
decltype(auto) invoke_with_tuple(ParameterTuple &&parameter_tuple)
Invoke the function with a tuple of parameters.
messages::SerializedMessage call(const messages::ParsedRequest &request) override
Call this method.
FunctionalMethod(messages::MethodName name, InputFunction &&function, std::shared_ptr< logging::Logger > logger)
Constructor.
void notify(const messages::ParsedNotification &notification) override
Notify this method.
FunctionalMethod(messages::MethodNameView name, InputFunction &&function, std::shared_ptr< logging::Logger > logger)
Constructor.
messages::MethodNameView name() const noexcept override
Get the method name.
messages::SerializedMessage call(const messages::ParsedRequest &request) override
Call this method.
Class of methods implemented by function objects.
Class of exceptions in methods.
const msgpack::object & object() const noexcept
Get the object in msgpack library.
const char * what() const noexcept override
Get the message of this exception.
Definition of format_msgpack_object function.
Definition of IMethod class.
Definition of Logger class.
#define MSGPACK_RPC_DEBUG(LOGGER_PTR,...)
Write a debug log.
Definition logger.h:186
Definition of MessageSerializer class.
Definition of MethodException class.
Definition of MethodName class.
Definition of MethodNameView class.
Namespace of methods in MessagePack-RPC.
std::unique_ptr< FunctionalMethod< Signature, Function > > create_functional_method(messages::MethodName name, Function &&function, std::shared_ptr< logging::Logger > logger)
Create a method implemented by a function object.
impl::FmtMsgpackObjectProxy format_msgpack_object(const msgpack::object &object)
Format an object in msgpack library using fmt library.
STL namespace.
Definition of ParsedNotification class.
Definition of ParsedRequest class.
Definition of SerializedMessage class.