feat: Begins using swift argument parser and creating cli client dependency
All checks were successful
CI / Run Tests (push) Successful in 4m27s

This commit is contained in:
2024-11-16 22:32:32 -05:00
parent 3416ce1003
commit 6472d3cd1e
19 changed files with 657 additions and 342 deletions

View File

@@ -9,16 +9,16 @@ import NIO
public extension DependencyValues {
/// A dependency that is responsible for managing the connection to
/// an MQTT broker.
/// an MQTT broker, listen to topics, and publish values back to the
/// broker.
var mqtt: MQTTManager {
get { self[MQTTManager.self] }
set { self[MQTTManager.self] = newValue }
}
}
/// Represents the interface needed for the ``MQTTConnectionService``.
/// Represents the interface needed to connect, listen, and publish to an MQTT broker.
///
/// See ``MQTTConnectionManagerLive`` module for live implementation.
@DependencyClient
public struct MQTTManager: Sendable {
@@ -28,6 +28,8 @@ public struct MQTTManager: Sendable {
public var connect: @Sendable () async throws -> Void
/// Create a stream of connection events.
///
/// - SeeAlso: ``Event``
public var connectionStream: @Sendable () throws -> AsyncStream<Event>
private var _listen: @Sendable ([String], MQTTQoS) async throws -> ListenStream
@@ -38,10 +40,24 @@ public struct MQTTManager: Sendable {
/// Shutdown the connection to the MQTT broker.
public var shutdown: @Sendable () -> Void
/// Perform an operation with the underlying MQTTClient, this can be useful in
/// tests, so this module needs imported with `@_spi(Testing) import` to use this method.
private var _withClient: @Sendable ((MQTTClient) async throws -> Void) async throws -> Void
public init(
connect: @escaping @Sendable () async throws -> Void,
connectionStream: @escaping @Sendable () throws -> AsyncStream<MQTTManager.Event>,
listen: @escaping @Sendable ([String], MQTTQoS) async throws -> MQTTManager.ListenStream,
publish: @escaping @Sendable (MQTTManager.PublishRequest) async throws -> Void,
shutdown: @escaping @Sendable () -> Void,
withClient: @escaping @Sendable ((MQTTClient) async throws -> Void) async throws -> Void = { _ in unimplemented() }
) {
self.connect = connect
self.connectionStream = connectionStream
self._listen = listen
self.publish = publish
self.shutdown = shutdown
self._withClient = withClient
}
/// Create an async stream that listens for changes to the given topics.
///
/// - Parameters:
@@ -77,18 +93,20 @@ public struct MQTTManager: Sendable {
_ payload: ByteBuffer,
to topicName: String,
qos: MQTTQoS,
retain: Bool = false
retain: Bool = false,
properties: MQTTProperties = .init()
) async throws {
try await publish(.init(
topicName: topicName,
payload: payload,
qos: qos,
retain: retain
retain: retain,
properties: properties
))
}
/// Perform an operation with the underlying MQTTClient, this can be useful in
/// tests, so this module needs imported with `@_spi(Testing) import` to use this method.
/// tests, so this module needs imported with `@_spi(Internal) import MQTTManager` to use this method.
@_spi(Internal)
public func withClient(
_ callback: @Sendable (MQTTClient) async throws -> Void
@@ -98,7 +116,7 @@ public struct MQTTManager: Sendable {
/// Represents connection events that clients can listen for and
/// react accordingly.
public enum Event: Sendable {
public enum Event: Equatable, Sendable {
case connected
case disconnected
case shuttingDown
@@ -106,7 +124,7 @@ public struct MQTTManager: Sendable {
/// Represents the parameters required to publish a new value to the
/// MQTT broker.
public struct PublishRequest: Equatable, Sendable {
public struct PublishRequest: Sendable {
/// The topic to publish the new value to.
public let topicName: String
@@ -120,6 +138,8 @@ public struct MQTTManager: Sendable {
/// The retain flag for the request.
public let retain: Bool
public let properties: MQTTProperties
/// Create a new publish request.
///
/// - Parameters:
@@ -131,12 +151,14 @@ public struct MQTTManager: Sendable {
topicName: String,
payload: ByteBuffer,
qos: MQTTQoS,
retain: Bool
retain: Bool,
properties: MQTTProperties
) {
self.topicName = topicName
self.payload = payload
self.qos = qos
self.retain = retain
self.properties = properties
}
}
@@ -164,7 +186,7 @@ public extension MQTTManager {
.removeDuplicates()
.eraseToStream()
},
_listen: { topics, qos in
listen: { topics, qos in
try await manager.listen(to: topics, qos: qos)
},
publish: { request in
@@ -174,19 +196,20 @@ public extension MQTTManager {
return
}
logger?.trace("Begin publishing to topic: \(topic)")
defer { logger?.trace("Done publishing to topic: \(topic)") }
defer { logger?.debug("Done publishing to topic: \(topic)") }
try await client.publish(
to: request.topicName,
payload: request.payload,
qos: request.qos,
retain: request.retain
)
retain: request.retain,
properties: request.properties
).get()
},
shutdown: {
Task { try await client.shutdown() }
manager.shutdown()
},
_withClient: { callback in
withClient: { callback in
try await callback(client)
}
)