81 lines
2.8 KiB
Swift
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)
|
|
}
|
|
}
|
|
}
|