Tusker/Tusker/SemiCaseSensitiveComparator...

62 lines
1.9 KiB
Swift

//
// SemiCaseSensitiveComparator.swift
// Tusker
//
// Created by Shadowfacts on 11/30/22.
// Copyright © 2022 Shadowfacts. All rights reserved.
//
import Foundation
/// A comparator that sorts objects with a string key path case insensitively unless they're the same, in which case uppercase comes after lowercase.
struct SemiCaseSensitiveComparator: SortComparator {
var order: SortOrder = .forward
typealias Compared = String
static func keyPath<Object>(_ keyPath: KeyPath<Object, String>) -> KeyPathComparator<Object> {
return KeyPathComparator(keyPath, comparator: SemiCaseSensitiveComparator())
}
func compare(_ lhs: String, _ rhs: String) -> ComparisonResult {
let result = doCompare(lhs, rhs)
if case .reverse = order {
switch result {
case .orderedDescending:
return .orderedAscending
case .orderedAscending:
return .orderedDescending
case .orderedSame:
return .orderedSame
}
} else {
return result
}
}
private func doCompare(_ lhs: String, _ rhs: String) -> ComparisonResult {
for (l, r) in zip(lhs, rhs) {
let lLower = l.lowercased()
let rLower = r.lowercased()
if lLower < rLower {
return .orderedAscending
} else if lLower > rLower {
return .orderedDescending
} else {
if l < r {
return .orderedDescending
} else if l > r {
return .orderedAscending
}
}
}
if lhs.count > rhs.count {
return .orderedDescending
} else if lhs.count < rhs.count {
return .orderedAscending
} else {
return .orderedSame
}
}
}