Files

81 lines
2.8 KiB
Swift

// SPDX-FileCopyrightText: 2026 Kaede Akino
// SPDX-License-Identifier: GPL-3.0-only
import Foundation
import TermindDomain
public nonisolated enum RemoteFileSortField: String, CaseIterable, Sendable {
case name
case modified
case size
case kind
public var defaultDirection: RemoteFileSortDirection {
switch self {
case .modified, .size: .descending
case .name, .kind: .ascending
}
}
}
public nonisolated enum RemoteFileSortDirection: String, Sendable {
case ascending
case descending
public mutating func toggle() {
self = self == .ascending ? .descending : .ascending
}
}
public nonisolated struct RemoteFileSortDescriptor: Sendable {
public var field: RemoteFileSortField
public var direction: RemoteFileSortDirection
public init(field: RemoteFileSortField = .name, direction: RemoteFileSortDirection = .ascending) {
self.field = field
self.direction = direction
}
public func precedes(
_ lhs: RemoteFile, _ rhs: RemoteFile,
lhsKind: String? = nil, rhsKind: String? = nil
) -> Bool {
if lhs.isDirectory != rhs.isDirectory { return lhs.isDirectory }
let primary = compare(lhs, rhs, lhsKind: lhsKind, rhsKind: rhsKind)
if primary != .orderedSame {
return direction == .ascending
? primary == .orderedAscending
: primary == .orderedDescending
}
let name = lhs.name.localizedStandardCompare(rhs.name)
if name != .orderedSame { return name == .orderedAscending }
return lhs.path.localizedStandardCompare(rhs.path) == .orderedAscending
}
private func compare(
_ lhs: RemoteFile, _ rhs: RemoteFile,
lhsKind: String?, rhsKind: String?
) -> ComparisonResult {
switch field {
case .name:
return lhs.name.localizedStandardCompare(rhs.name)
case .modified:
switch (lhs.modifiedAt, rhs.modifiedAt) {
case (.none, .none): return .orderedSame
case (.none, .some): return direction == .ascending ? .orderedDescending : .orderedAscending
case (.some, .none): return direction == .ascending ? .orderedAscending : .orderedDescending
case (.some(let left), .some(let right)):
return left == right
? .orderedSame : (left < right ? .orderedAscending : .orderedDescending)
}
case .size:
return lhs.size == rhs.size
? .orderedSame
: (lhs.size < rhs.size ? .orderedAscending : .orderedDescending)
case .kind:
return (lhsKind ?? lhs.sftpKindDescription)
.localizedStandardCompare(rhsKind ?? rhs.sftpKindDescription)
}
}
}