summaryrefslogtreecommitdiff
path: root/src/sdbuscpp_no_throw_helper.hh
diff options
context:
space:
mode:
authorJoel Klinghed <the_jk@spawned.biz>2025-10-20 21:29:01 +0200
committerJoel Klinghed <the_jk@spawned.biz>2025-10-20 21:29:01 +0200
commite8dc8edad7cdf194091f0479b70b154e872f57ef (patch)
tree5431680ce100812b9b3bea32a7847e7dcfdcf29d /src/sdbuscpp_no_throw_helper.hh
parent0687ec31d1d75500beaee0e983ebf73d7c4517f7 (diff)
bt & main: Add optional player for device
Diffstat (limited to 'src/sdbuscpp_no_throw_helper.hh')
-rw-r--r--src/sdbuscpp_no_throw_helper.hh61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/sdbuscpp_no_throw_helper.hh b/src/sdbuscpp_no_throw_helper.hh
new file mode 100644
index 0000000..4696895
--- /dev/null
+++ b/src/sdbuscpp_no_throw_helper.hh
@@ -0,0 +1,61 @@
+#ifndef SDBUSCPP_NO_THROW_HELPER_HH
+#define SDBUSCPP_NO_THROW_HELPER_HH
+
+// SDBUSCPP_ENABLE_RELAXED_DICT2STRUCT_DESERIALIZATION +
+// SDBUSCPP_REGISTER_STRUCT still references throw
+#define SDBUSCPP_REGISTER_STRUCT_NO_THROW(STRUCT, ...) \
+ namespace sdbus { \
+ static_assert(SDBUSCPP_PP_NARG(__VA_ARGS__) <= 16, \
+ "Not more than 16 struct members are supported, please open " \
+ "an issue if you need more"); \
+ \
+ template <> \
+ struct signature_of<STRUCT> \
+ : signature_of<sdbus::Struct<SDBUSCPP_STRUCT_MEMBER_TYPES( \
+ STRUCT, __VA_ARGS__)>> {}; \
+ \
+ inline auto as_dictionary_if_struct(const STRUCT& object) { \
+ return as_dictionary<STRUCT>(object); \
+ } \
+ \
+ inline sdbus::Message& operator<<(sdbus::Message& msg, \
+ const STRUCT& items) { \
+ return msg << sdbus::Struct{std::forward_as_tuple( \
+ SDBUSCPP_STRUCT_MEMBERS(items, __VA_ARGS__))}; \
+ } \
+ \
+ inline Message& operator<<(Message& msg, const as_dictionary<STRUCT>& s) { \
+ if constexpr (!nested_struct_as_dict_serialization_v<STRUCT>) \
+ return msg.serializeDictionary<std::string, Variant>( \
+ {SDBUSCPP_STRUCT_MEMBERS_AS_DICT_ENTRIES(s.m_struct, __VA_ARGS__)}); \
+ else \
+ return msg.serializeDictionary<std::string, Variant>( \
+ {SDBUSCPP_STRUCT_MEMBERS_AS_NESTED_DICT_ENTRIES(s.m_struct, \
+ __VA_ARGS__)}); \
+ } \
+ \
+ inline Message& operator>>(Message& msg, STRUCT& s) { \
+ /* First, try to deserialize as a struct */ \
+ if (msg.peekType().first == signature_of<STRUCT>::type_value) { \
+ Struct sdbusStruct{ \
+ std::forward_as_tuple(SDBUSCPP_STRUCT_MEMBERS(s, __VA_ARGS__))}; \
+ return msg >> sdbusStruct; \
+ } \
+ \
+ /* Otherwise try to deserialize as a dictionary of strings to variants */ \
+ \
+ return msg.deserializeDictionary<std::string, Variant>( \
+ [&s](const auto& dictEntry) { \
+ const std::string& key = \
+ dictEntry \
+ .first; /* Intentionally not using structured bindings */ \
+ const Variant& value = dictEntry.second; \
+ \
+ using namespace std::string_literals; \
+ /* This also handles members which are structs serialized as dict of strings to variants, recursively */ \
+ SDBUSCPP_FIND_AND_DESERIALIZE_STRUCT_MEMBERS(s, __VA_ARGS__); \
+ }); \
+ } \
+ }
+
+#endif // SDBUSCPP_NO_THROW_HELPER_HH