Viam C++ SDK current
Loading...
Searching...
No Matches
service_helper.hpp
1#pragma once
2
3#include <type_traits>
4
5#include <viam/sdk/resource/resource_server_base.hpp>
6
7namespace viam {
8namespace sdk {
9
11 public:
12 ::grpc::Status fail(::grpc::StatusCode code, const char* message) const noexcept;
13
14 ::grpc::Status failNoRequest() const noexcept;
15
16 ::grpc::Status failNoResource(const std::string& name) const noexcept;
17
18 ::grpc::Status failStdException(const std::exception& xcp) const noexcept;
19
20 ::grpc::Status failUnknownException() const noexcept;
21
22 protected:
23 explicit ServiceHelperBase(const char* method) noexcept : method_{method} {}
24
25 private:
26 const char* method_;
27};
28
29template <typename ServiceType, typename RequestType>
31 public:
32 ServiceHelper(const char* method, ResourceServer* rs, RequestType* request) noexcept
33 : ServiceHelperBase{method}, rs_{rs}, request_{request} {};
34
35 template <typename Callable>
36 ::grpc::Status operator()(Callable&& callable) const noexcept try {
37 if (!request_) {
38 return failNoRequest();
39 }
40 const auto resource = rs_->resource_manager()->resource<ServiceType>(request_->name());
41 if (!resource) {
42 return failNoResource(request_->name());
43 }
44 return invoke_(std::forward<Callable>(callable), std::move(resource));
45 } catch (const std::exception& xcp) {
46 return failStdException(xcp);
47 } catch (...) {
48 return failUnknownException();
49 }
50
51 auto getExtra() const {
52 return request_->has_extra() ? struct_to_map(request_->extra()) : AttributeMap{};
53 }
54
55 private:
56 template <typename Callable, typename... Args>
57 using is_void_result = std::is_void<std::result_of_t<Callable(Args...)>>;
58
59 // Implementation of `invoke_` for a Callable returning non-void,
60 // presumably an error return, which we return as a
61 // ::grpc::Status.
62 template <typename Callable,
63 typename ResourcePtrType,
64 std::enable_if_t<!is_void_result<Callable, ServiceHelper&, ResourcePtrType&&>::value,
65 bool> = true>
66 ::grpc::Status invoke_(Callable&& callable, ResourcePtrType&& resource) const {
67 return std::forward<Callable>(callable)(*this, std::forward<ResourcePtrType>(resource));
68 }
69
70 // Implementation of `invoke_` for a Callable returning void,
71 // which is therefore either non-failing or communicates errors by
72 // throwing exceptions. We return an OK status automatically.
73 template <typename Callable,
74 typename ResourcePtrType,
75 std::enable_if_t<is_void_result<Callable, ServiceHelper&, ResourcePtrType&&>::value,
76 bool> = true>
77 ::grpc::Status invoke_(Callable&& callable, ResourcePtrType&& resource) const {
78 std::forward<Callable>(callable)(*this, std::forward<ResourcePtrType>(resource));
79 return {};
80 }
81
82 ResourceServer* rs_;
83 RequestType* request_;
84};
85
86template <typename ServiceType, typename RequestType>
87auto make_service_helper(const char* method, ResourceServer* rs, RequestType* request) {
88 return ServiceHelper<ServiceType, RequestType>{method, rs, request};
89}
90
91} // namespace sdk
92} // namespace viam
Definition resource_server_base.hpp:8
Definition service_helper.hpp:10
Definition service_helper.hpp:30