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č committed 2024-04-24 20:20:29 +02:00
1 parent fe21ee9656
commit 42f0bd07c0
60 files changed
+1085 -621

No files matched your search

+42 -12
View File
@@ -41,6 +41,7 @@
namespace sdbus {
class Signal;
class IConnection;
class ObjectPath;
}
namespace sdbus {
@@ -89,7 +90,7 @@ namespace sdbus {
*/
template < typename... VTableItems
, typename = std::enable_if_t<(is_one_of_variants_types<VTableItem, std::decay_t<VTableItems>> && ...)> >
void addVTable(std::string interfaceName, VTableItems&&... items);
void addVTable(InterfaceName interfaceName, VTableItems&&... items);
/*!
* @brief Adds a declaration of methods, properties and signals of the object at a given interface
@@ -114,7 +115,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
virtual void addVTable(std::string interfaceName, std::vector<VTableItem> vtable) = 0;
virtual void addVTable(InterfaceName interfaceName, std::vector<VTableItem> vtable) = 0;
/*!
* @brief Adds a declaration of methods, properties and signals of the object at a given interface
@@ -141,7 +142,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
[[nodiscard]] virtual Slot addVTable(std::string interfaceName, std::vector<VTableItem> vtable, return_slot_t) = 0;
[[nodiscard]] virtual Slot addVTable(InterfaceName interfaceName, std::vector<VTableItem> vtable, return_slot_t) = 0;
/*!
* @brief A little more convenient overload of addVTable() above
@@ -188,7 +189,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
[[nodiscard]] virtual Signal createSignal(const std::string& interfaceName, const std::string& signalName) = 0;
[[nodiscard]] virtual Signal createSignal(const InterfaceName& interfaceName, const SignalName& signalName) = 0;
/*!
* @brief Emits signal for this object path
@@ -201,6 +202,28 @@ namespace sdbus {
*/
virtual void emitSignal(const sdbus::Signal& message) = 0;
/*!
* @brief Emits signal on D-Bus
*
* @param[in] signalName Name of the signal
* @return A helper object for convenient emission of signals
*
* This is a high-level, convenience way of emitting D-Bus signals that abstracts
* from the D-Bus message concept. Signal arguments are automatically serialized
* in a message and D-Bus signatures automatically deduced from the provided native arguments.
*
* Example of use:
* @code
* int arg1 = ...;
* double arg2 = ...;
* SignalName fooSignal{"fooSignal"};
* object_.emitSignal(fooSignal).onInterface("com.kistler.foo").withArguments(arg1, arg2);
* @endcode
*
* @throws sdbus::Error in case of failure
*/
[[nodiscard]] SignalEmitter emitSignal(const SignalName& signalName);
/*!
* @brief Emits signal on D-Bus
*
@@ -230,7 +253,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
virtual void emitPropertiesChangedSignal(const std::string& interfaceName, const std::vector<std::string>& propNames) = 0;
virtual void emitPropertiesChangedSignal(const InterfaceName& interfaceName, const std::vector<PropertyName>& propNames) = 0;
/*!
* @brief Emits PropertyChanged signal for all properties on a given interface of this object path
@@ -239,7 +262,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
virtual void emitPropertiesChangedSignal(const std::string& interfaceName) = 0;
virtual void emitPropertiesChangedSignal(const InterfaceName& interfaceName) = 0;
/*!
* @brief Emits InterfacesAdded signal on this object path
@@ -264,7 +287,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
virtual void emitInterfacesAddedSignal(const std::vector<std::string>& interfaces) = 0;
virtual void emitInterfacesAddedSignal(const std::vector<InterfaceName>& interfaces) = 0;
/*!
* @brief Emits InterfacesRemoved signal on this object path
@@ -286,7 +309,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
virtual void emitInterfacesRemovedSignal(const std::vector<std::string>& interfaces) = 0;
virtual void emitInterfacesRemovedSignal(const std::vector<InterfaceName>& interfaces) = 0;
/*!
* @brief Adds an ObjectManager interface at the path of this D-Bus object
@@ -322,7 +345,7 @@ namespace sdbus {
/*!
* @brief Returns object path of the underlying DBus object
*/
[[nodiscard]] virtual const std::string& getObjectPath() const = 0;
[[nodiscard]] virtual const ObjectPath& getObjectPath() const = 0;
/*!
* @brief Provides access to the currently processed D-Bus message
@@ -342,13 +365,20 @@ namespace sdbus {
// Out-of-line member definitions
inline SignalEmitter IObject::emitSignal(const std::string& signalName)
inline SignalEmitter IObject::emitSignal(const SignalName& signalName)
{
return SignalEmitter(*this, signalName);
}
inline SignalEmitter IObject::emitSignal(const std::string& signalName)
{
// Down-cast through static cast for performance reasons (no extra copy and object construction needed)
static_assert(sizeof(signalName) == sizeof(SignalName));
return emitSignal(static_cast<const SignalName&>(signalName));
}
template <typename... VTableItems, typename>
void IObject::addVTable(std::string interfaceName, VTableItems&&... items)
void IObject::addVTable(InterfaceName interfaceName, VTableItems&&... items)
{
addVTable(std::move(interfaceName), {std::forward<VTableItems>(items)...});
}
@@ -382,7 +412,7 @@ namespace sdbus {
* auto proxy = sdbus::createObject(connection, "/com/kistler/foo");
* @endcode
*/
[[nodiscard]] std::unique_ptr<sdbus::IObject> createObject(sdbus::IConnection& connection, std::string objectPath);
[[nodiscard]] std::unique_ptr<sdbus::IObject> createObject(sdbus::IConnection& connection, ObjectPath objectPath);
}