Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support enums in D-Bus serialization and signatures #416

Merged
merged 4 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion include/sdbus-c++/Message.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@

#include <sdbus-c++/TypeTraits.h>
#include <sdbus-c++/Error.h>
#include <array>
#include <string>
#include <utility>
#include <vector>
#include <array>
#if __cplusplus >= 202002L
#include <span>
#endif
Expand Down Expand Up @@ -100,6 +101,8 @@ namespace sdbus {
template <typename _Element, std::size_t _Extent>
Message& operator<<(const std::span<_Element, _Extent>& items);
#endif
template <typename _Enum, typename = std::enable_if_t<std::is_enum_v<_Enum>>>
Message& operator<<(const _Enum& item);
template <typename _Key, typename _Value, typename _Compare, typename _Allocator>
Message& operator<<(const std::map<_Key, _Value, _Compare, _Allocator>& items);
template <typename _Key, typename _Value, typename _Hash, typename _KeyEqual, typename _Allocator>
Expand Down Expand Up @@ -132,6 +135,8 @@ namespace sdbus {
template <typename _Element, std::size_t _Extent>
Message& operator>>(std::span<_Element, _Extent>& items);
#endif
template <typename _Enum, typename = std::enable_if_t<std::is_enum_v<_Enum>>>
Message& operator>>(_Enum& item);
template <typename _Key, typename _Value, typename _Compare, typename _Allocator>
Message& operator>>(std::map<_Key, _Value, _Compare, _Allocator>& items);
template <typename _Key, typename _Value, typename _Hash, typename _KeyEqual, typename _Allocator>
Expand Down Expand Up @@ -332,6 +337,12 @@ namespace sdbus {
}
#endif

template <typename _Enum, typename>
inline Message& Message::operator<<(const _Enum &item)
{
return operator<<(static_cast<std::underlying_type_t<_Enum>>(item));
}

template <typename _Array>
inline void Message::serializeArray(const _Array& items)
{
Expand Down Expand Up @@ -457,6 +468,15 @@ namespace sdbus {
}
#endif

template <typename _Enum, typename>
inline Message& Message::operator>>(_Enum& item)
{
std::underlying_type_t<_Enum> val;
*this >> val;
item = static_cast<_Enum>(val);
return *this;
}

template <typename _Array>
inline void Message::deserializeArray(_Array& items)
{
Expand Down
11 changes: 8 additions & 3 deletions include/sdbus-c++/TypeTraits.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ namespace sdbus {
inline constexpr dont_expect_reply_t dont_expect_reply{};

// Template specializations for getting D-Bus signatures from C++ types
template <typename _T>
template <typename _T, typename _Enable = void>
sangelovic marked this conversation as resolved.
Show resolved Hide resolved
struct signature_of
{
static constexpr bool is_valid = false;
Expand All @@ -120,7 +120,7 @@ namespace sdbus {

template <typename _T>
struct signature_of<_T&>
: public signature_of<_T>
: public signature_of<_T>
{};

template <>
Expand Down Expand Up @@ -405,6 +405,12 @@ namespace sdbus {
};
#endif

template <typename _Enum>
struct signature_of<_Enum, typename std::enable_if_t<std::is_enum_v<_Enum>>>
: public signature_of<std::underlying_type_t<_Enum>>
{};


template <typename _Key, typename _Value, typename _Compare, typename _Allocator>
struct signature_of<std::map<_Key, _Value, _Compare, _Allocator>>
{
Expand All @@ -429,7 +435,6 @@ namespace sdbus {
}
};


// Function traits implementation inspired by (c) kennytm,
// https://github.com/kennytm/utils/blob/master/traits.hpp
template <typename _Type>
Expand Down
18 changes: 18 additions & 0 deletions tests/unittests/Message_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,24 @@ TEST(AMessage, CanCarryDBusArrayOfNontrivialTypesGivenAsStdSpan)
}
#endif

TEST(AMessage, CanCarryAnEnumValue)
{
auto msg = sdbus::createPlainMessage();

enum class EnumA : int16_t {X = 5} aWritten{EnumA::X};
enum EnumB {Y = 11} bWritten{EnumB::Y};

msg << aWritten << bWritten;
msg.seal();

EnumA aRead{};
EnumB bRead{};
msg >> aRead >> bRead;

ASSERT_THAT(aRead, Eq(aWritten));
ASSERT_THAT(bRead, Eq(bWritten));
}

TEST(AMessage, ThrowsWhenDestinationStdArrayIsTooSmallDuringDeserialization)
{
auto msg = sdbus::createPlainMessage();
Expand Down
23 changes: 22 additions & 1 deletion tests/unittests/TypeTraits_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,21 @@ namespace
static std::string getDBusTypeSignature();
};

enum class SomeEnumClass : uint8_t
{
A, B, C
};

enum struct SomeEnumStruct : int64_t
{
A, B, C
};

enum SomeClassicEnum
{
A, B, C
};

#define TYPE(...) \
template <> \
std::string Type2DBusTypeSignatureConversion<__VA_ARGS__>::getDBusTypeSignature() \
Expand Down Expand Up @@ -79,8 +94,11 @@ namespace
TYPE(std::vector<int16_t>)HAS_DBUS_TYPE_SIGNATURE("an")
TYPE(std::array<int16_t, 3>)HAS_DBUS_TYPE_SIGNATURE("an")
#if __cplusplus >= 202002L
TYPE(std::span<int16_t>)HAS_DBUS_TYPE_SIGNATURE("ao")
TYPE(std::span<int16_t>)HAS_DBUS_TYPE_SIGNATURE("an")
#endif
TYPE(SomeEnumClass)HAS_DBUS_TYPE_SIGNATURE("y")
TYPE(SomeEnumStruct)HAS_DBUS_TYPE_SIGNATURE("x")
TYPE(SomeClassicEnum)HAS_DBUS_TYPE_SIGNATURE("u")
TYPE(std::map<int32_t, int64_t>)HAS_DBUS_TYPE_SIGNATURE("a{ix}")
TYPE(std::unordered_map<int32_t, int64_t>)HAS_DBUS_TYPE_SIGNATURE("a{ix}")
using ComplexType = std::map<
Expand Down Expand Up @@ -127,6 +145,9 @@ namespace
#if __cplusplus >= 202002L
, std::span<int16_t>
#endif
, SomeEnumClass
, SomeEnumStruct
, SomeClassicEnum
, std::map<int32_t, int64_t>
, std::unordered_map<int32_t, int64_t>
, ComplexType
Expand Down
Loading