`swift-format lint --strict --recursive Termind TermindTests
TermindMCPBridge` is in the contribution instructions but had never been
run to completion: 4133 violations across 141 files, most of them
indentation and line breaking the pretty-printer would have settled on
its own.
`swift-format format -i` accounts for all but five. The rest are
lint-only rules it will not rewrite for you:
- `SSHKeyMaterial` declared its libssh2 entry point in the C symbol's
own spelling. `@_silgen_name` already carries the linkage name, so the
Swift side is free to be `libssh2PublicKeyFromPrivateMemory`.
- Four `.forEach { ... }` calls become for-in loops, two in
`PortForwardingController` and two in tests.
Formatting only, and checked as such rather than assumed: all 5409
string literals under `Termind` are byte-identical across the change, so
no localization key moved. Comparing whitespace-stripped token streams
leaves 43 files with any real change, and each is one of the rules
above, a dropped semicolon, a `case a, b` split onto separate lines with
its raw values kept explicit, or a file-scope `private` respelled
`fileprivate` — which is the same access level in that position.
Builds, and the suite stays at 975 of 975.
89 lines
2.9 KiB
Swift
89 lines
2.9 KiB
Swift
import Foundation
|
|
|
|
nonisolated struct HostLibrarySnapshot: Equatable, Sendable {
|
|
var hosts: [Host]
|
|
var groups: [HostGroup]
|
|
|
|
static let empty = HostLibrarySnapshot(hosts: [], groups: [])
|
|
}
|
|
|
|
@MainActor
|
|
protocol HostRepository: AnyObject {
|
|
func snapshot() throws -> RepositoryChange<HostLibrarySnapshot>
|
|
func changes() -> AsyncStream<RepositoryChange<HostLibrarySnapshot>>
|
|
func refresh() throws
|
|
func upsertHost(_ host: Host) throws
|
|
func deletionImpact(for hostID: Host.ID) throws -> HostDeletionImpact
|
|
func requestHostDeletion(_ hostID: Host.ID) throws
|
|
func clearReferencesForDeletedHost(_ hostID: Host.ID) throws
|
|
func finalizeHostDeletion(_ hostID: Host.ID) throws
|
|
}
|
|
|
|
@MainActor
|
|
final class InMemoryHostRepository: HostRepository {
|
|
private var value: HostLibrarySnapshot
|
|
private var revision: Int64 = 0
|
|
private var continuations: [UUID: AsyncStream<RepositoryChange<HostLibrarySnapshot>>.Continuation] = [:]
|
|
|
|
init(snapshot: HostLibrarySnapshot = .empty) { value = snapshot }
|
|
|
|
func snapshot() throws -> RepositoryChange<HostLibrarySnapshot> {
|
|
RepositoryChange(
|
|
revision: revision,
|
|
value: value,
|
|
reason: .initial
|
|
)
|
|
}
|
|
|
|
func changes() -> AsyncStream<RepositoryChange<HostLibrarySnapshot>> {
|
|
let id = UUID()
|
|
return AsyncStream { continuation in
|
|
continuations[id] = continuation
|
|
continuation.yield(try! snapshot())
|
|
continuation.onTermination = { [weak self] _ in
|
|
Task { @MainActor in self?.continuations[id] = nil }
|
|
}
|
|
}
|
|
}
|
|
|
|
func refresh() throws {
|
|
revision &+= 1
|
|
let change = RepositoryChange(
|
|
revision: revision,
|
|
value: value,
|
|
reason: .refresh
|
|
)
|
|
for continuation in continuations.values { continuation.yield(change) }
|
|
}
|
|
|
|
func upsertHost(_ host: Host) throws {
|
|
if let index = value.hosts.firstIndex(where: { $0.id == host.id }) {
|
|
value.hosts[index] = host
|
|
} else {
|
|
value.hosts.append(host)
|
|
}
|
|
try publish(.mutation)
|
|
}
|
|
|
|
func deletionImpact(for hostID: Host.ID) throws -> HostDeletionImpact {
|
|
HostDeletionImpact(
|
|
jumpHostReferences: value.hosts.filter { $0.jumpHostID == hostID }.count,
|
|
snippetReferences: 0, forwardingRules: 0
|
|
)
|
|
}
|
|
|
|
func requestHostDeletion(_ hostID: Host.ID) throws {
|
|
value.hosts.removeAll { $0.id == hostID }
|
|
try publish(.mutation)
|
|
}
|
|
|
|
func clearReferencesForDeletedHost(_ hostID: Host.ID) throws {}
|
|
func finalizeHostDeletion(_ hostID: Host.ID) throws {}
|
|
|
|
private func publish(_ reason: RepositoryChangeReason) throws {
|
|
revision &+= 1
|
|
let change = RepositoryChange(revision: revision, value: value, reason: reason)
|
|
for continuation in continuations.values { continuation.yield(change) }
|
|
}
|
|
}
|