aboutsummaryrefslogtreecommitdiff
path: root/pw_rpc/public/pw_rpc/internal/method_lookup.h
diff options
context:
space:
mode:
Diffstat (limited to 'pw_rpc/public/pw_rpc/internal/method_lookup.h')
-rw-r--r--pw_rpc/public/pw_rpc/internal/method_lookup.h64
1 files changed, 64 insertions, 0 deletions
diff --git a/pw_rpc/public/pw_rpc/internal/method_lookup.h b/pw_rpc/public/pw_rpc/internal/method_lookup.h
new file mode 100644
index 000000000..7383a0160
--- /dev/null
+++ b/pw_rpc/public/pw_rpc/internal/method_lookup.h
@@ -0,0 +1,64 @@
+// Copyright 2020 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+#pragma once
+
+#include "pw_rpc/internal/method.h"
+
+namespace pw::rpc::internal {
+
+// Gets a Method object from a generated RPC service class. Getter functions are
+// provided for each supported method implementation. The
+//
+// To ensure the MethodUnion actually holds the requested method type, the
+// method ID is accessed in a static_assert. It is invalid to access an unset
+// union member in a constant expression, so this results in a compiler error.
+class MethodLookup {
+ public:
+ template <typename Service, uint32_t kMethodId>
+ static constexpr const auto& GetRawMethod() {
+ const auto& method = GetMethodUnion<Service, kMethodId>().raw_method();
+ static_assert(method.id() == kMethodId, "Incorrect method implementation");
+ return method;
+ }
+
+ template <typename Service, uint32_t kMethodId>
+ static constexpr const auto& GetNanopbMethod() {
+ const auto& method = GetMethodUnion<Service, kMethodId>().nanopb_method();
+ static_assert(method.id() == kMethodId, "Incorrect method implementation");
+ return method;
+ }
+
+ private:
+ template <typename Service, uint32_t kMethodId>
+ static constexpr const auto& GetMethodUnion() {
+ constexpr auto method = GetMethodUnionPointer<Service>(kMethodId);
+ static_assert(method != nullptr,
+ "The selected function is not an RPC service method");
+ return *method;
+ }
+
+ template <typename Service>
+ static constexpr
+ typename decltype(GeneratedService<Service>::kMethods)::const_pointer
+ GetMethodUnionPointer(uint32_t kMethodId) {
+ for (size_t i = 0; i < GeneratedService<Service>::kMethodIds.size(); ++i) {
+ if (GeneratedService<Service>::kMethodIds[i] == kMethodId) {
+ return &GeneratedService<Service>::kMethods[i];
+ }
+ }
+ return nullptr;
+ }
+};
+
+} // namespace pw::rpc::internal