Files

85 lines
2.4 KiB
Swift

// SPDX-FileCopyrightText: 2026 Kaede Akino
// SPDX-License-Identifier: GPL-3.0-only
import Foundation
public nonisolated struct WorkspaceTemplate: Identifiable, Codable, Hashable, Sendable {
public var id: UUID
public var name: String
public var layout: WorkspaceTemplateLayout
public var isValid: Bool {
!name.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
&& layout.paneCount >= 1
&& layout.isValid
}
public init(id: UUID = UUID(), name: String, layout: WorkspaceTemplateLayout) {
self.id = id
self.name = name
self.layout = layout
}
}
public nonisolated enum WorkspaceTemplatePane: Codable, Hashable, Sendable {
case ssh(hostID: Host.ID)
case mosh(hostID: Host.ID)
case eternalTerminal(hostID: Host.ID)
case telnet(hostID: Host.ID)
case sftp(hostID: Host.ID)
case empty
public var hostID: Host.ID? {
switch self {
case .ssh(let hostID), .mosh(let hostID), .eternalTerminal(let hostID), .telnet(let hostID), .sftp(let hostID):
hostID
case .empty: nil
}
}
}
public nonisolated enum WorkspaceTemplateSplitAxis: String, Codable, Hashable, Sendable {
case horizontal
case vertical
}
public nonisolated indirect enum WorkspaceTemplateLayout: Codable, Hashable, Sendable {
case pane(WorkspaceTemplatePane)
case split(
axis: WorkspaceTemplateSplitAxis,
fraction: Double,
first: WorkspaceTemplateLayout,
second: WorkspaceTemplateLayout
)
public var paneCount: Int {
switch self {
case .pane: 1
case .split(_, _, let first, let second): first.paneCount + second.paneCount
}
}
public var hostIDs: [Host.ID] {
switch self {
case .pane(let pane): pane.hostID.map { [$0] } ?? []
case .split(_, _, let first, let second): first.hostIDs + second.hostIDs
}
}
public var panes: [WorkspaceTemplatePane] {
switch self {
case .pane(let pane): [pane]
case .split(_, _, let first, let second): first.panes + second.panes
}
}
public var isValid: Bool {
switch self {
case .pane:
true
case .split(_, let fraction, let first, let second):
fraction.isFinite && fraction > 0 && fraction < 1 && first.isValid && second.isValid
}
}
}