refactor: add strong types to public API (#414)

This introduces strong types for `std::string`-based D-Bus types. This facilitates safer, less error-prone and more expressive API.

What previously was `auto proxy = createProxy("org.sdbuscpp.concatenator", "/org/sdbuscpp/concatenator");` is now written like `auto proxy = createProxy(ServiceName{"org.sdbuscpp.concatenator"}, ObjectPath{"/org/sdbuscpp/concatenator"});`.

These types are:
  * `ObjectPath` type for the object path (the type has been around already but now is also used consistently in sdbus-c++ API for object path strings),
  * `InterfaceName` type for D-Bus interface names,
  * `BusName` (and its aliases `ServiceName` and `ConnectionName`) type for bus/service/connection names,
  * `MemberName` (and its aliases `MethodName`, `SignalName` and `PropertyName`) type for D-Bus method, signal and property names,
  * `Signature` type for the D-Bus signature (the type has been around already but now is also used consistently in sdbus-c++ API for signature strings),
  * `Error::Name` type for D-Bus error names.
This commit is contained in:
Stanislav Angelovič
2024-04-24 20:20:29 +02:00
parent fe21ee9656
commit 42f0bd07c0
60 changed files with 1085 additions and 621 deletions
+7 -2
View File
@@ -26,6 +26,7 @@
*/
#include "Connection.h"
#include "sdbus-c++/Types.h"
#include "unittests/mocks/SdBusMock.h"
#include <gtest/gtest.h>
@@ -207,12 +208,16 @@ TYPED_TEST_SUITE(AConnectionNameRequest, BusTypeTags);
TYPED_TEST(AConnectionNameRequest, DoesNotThrowOnSuccess)
{
EXPECT_CALL(*this->sdBusIntfMock_, sd_bus_request_name(_, _, _)).WillOnce(Return(1));
this->con_->requestName("org.sdbuscpp.somename");
sdbus::ConnectionName name{"org.sdbuscpp.somename"};
this->con_->requestName(name);
}
TYPED_TEST(AConnectionNameRequest, ThrowsOnFail)
{
sdbus::ConnectionName name{"org.sdbuscpp.somename"};
EXPECT_CALL(*this->sdBusIntfMock_, sd_bus_request_name(_, _, _)).WillOnce(Return(-1));
ASSERT_THROW(this->con_->requestName("org.sdbuscpp.somename"), sdbus::Error);
ASSERT_THROW(this->con_->requestName(name), sdbus::Error);
}
+4 -4
View File
@@ -270,7 +270,7 @@ TEST(AMessage, CanCarryDBusArrayOfNontrivialTypesGivenAsStdVector)
{
auto msg = sdbus::createPlainMessage();
const std::vector<sdbus::Signature> dataWritten{"s", "u", "b"};
const std::vector dataWritten{sdbus::Signature{"s"}, sdbus::Signature{"u"}, sdbus::Signature{"b"}};
msg << dataWritten;
msg.seal();
@@ -300,7 +300,7 @@ TEST(AMessage, CanCarryDBusArrayOfNontrivialTypesGivenAsStdArray)
{
auto msg = sdbus::createPlainMessage();
const std::array<sdbus::Signature, 3> dataWritten{"s", "u", "b"};
const std::array dataWritten{sdbus::Signature{"s"}, sdbus::Signature{"u"}, sdbus::Signature{"b"}};
msg << dataWritten;
msg.seal();
@@ -333,7 +333,7 @@ TEST(AMessage, CanCarryDBusArrayOfNontrivialTypesGivenAsStdSpan)
{
auto msg = sdbus::createPlainMessage();
const std::array<sdbus::Signature, 3> sourceArray{"s", "u", "b"};
const std::array sourceArray{sdbus::Signature{"s"}, sdbus::Signature{"u"}, sdbus::Signature{"b"}};
const std::span dataWritten{sourceArray};
msg << dataWritten;
@@ -433,7 +433,7 @@ TEST(AMessage, CanCarryAComplexType)
>
>;
ComplexType dataWritten = { {1, {{{5, {{"/some/object", true, 45, {{6, "hello"}, {7, "world"}}}}}}, "av", 3.14}}};
ComplexType dataWritten = { {1, {{{5, {{sdbus::ObjectPath{"/some/object"}, true, 45, {{6, "hello"}, {7, "world"}}}}}}, sdbus::Signature{"av"}, 3.14}}};
msg << dataWritten;
msg.seal();
+6
View File
@@ -85,6 +85,9 @@ namespace
TYPE(double)HAS_DBUS_TYPE_SIGNATURE("d")
TYPE(const char*)HAS_DBUS_TYPE_SIGNATURE("s")
TYPE(std::string)HAS_DBUS_TYPE_SIGNATURE("s")
TYPE(sdbus::BusName)HAS_DBUS_TYPE_SIGNATURE("s")
TYPE(sdbus::InterfaceName)HAS_DBUS_TYPE_SIGNATURE("s")
TYPE(sdbus::MemberName)HAS_DBUS_TYPE_SIGNATURE("s")
TYPE(sdbus::ObjectPath)HAS_DBUS_TYPE_SIGNATURE("o")
TYPE(sdbus::Signature)HAS_DBUS_TYPE_SIGNATURE("g")
TYPE(sdbus::Variant)HAS_DBUS_TYPE_SIGNATURE("v")
@@ -135,6 +138,9 @@ namespace
, double
, const char*
, std::string
, sdbus::BusName
, sdbus::InterfaceName
, sdbus::MemberName
, sdbus::ObjectPath
, sdbus::Signature
, sdbus::Variant
+6 -7
View File
@@ -322,7 +322,6 @@ TEST(ASignature, CanBeMovedLikeAStdString)
sdbus::Signature oSignature{aSignature};
ASSERT_THAT(sdbus::Signature{std::move(oSignature)}, Eq(sdbus::Signature(std::move(aSignature))));
ASSERT_THAT(std::string(oSignature), Eq(aSignature));
}
TEST(AUnixFd, DuplicatesAndOwnsFdUponStandardConstruction)
@@ -428,17 +427,17 @@ TEST(AUnixFd, TakesOverNewFdAndClosesOriginalFdOnAdoptingReset)
TEST(AnError, CanBeConstructedFromANameAndAMessage)
{
auto error = sdbus::Error("name", "message");
EXPECT_THAT(error.getName(), Eq<std::string>("name"));
auto error = sdbus::Error(sdbus::Error::Name{"org.sdbuscpp.error"}, "message");
EXPECT_THAT(error.getName(), Eq<std::string>("org.sdbuscpp.error"));
EXPECT_THAT(error.getMessage(), Eq<std::string>("message"));
}
TEST(AnError, CanBeConstructedFromANameOnly)
{
auto error1 = sdbus::Error("name");
auto error2 = sdbus::Error("name", nullptr);
EXPECT_THAT(error1.getName(), Eq<std::string>("name"));
EXPECT_THAT(error2.getName(), Eq<std::string>("name"));
auto error1 = sdbus::Error(sdbus::Error::Name{"org.sdbuscpp.error"});
auto error2 = sdbus::Error(sdbus::Error::Name{"org.sdbuscpp.error"}, nullptr);
EXPECT_THAT(error1.getName(), Eq<std::string>("org.sdbuscpp.error"));
EXPECT_THAT(error2.getName(), Eq<std::string>("org.sdbuscpp.error"));
EXPECT_THAT(error1.getMessage(), Eq<std::string>(""));
EXPECT_THAT(error2.getMessage(), Eq<std::string>(""));