46 lines
1.5 KiB
Swift
46 lines
1.5 KiB
Swift
import Foundation
|
|
|
|
public extension OfflineLibrarySnapshot {
|
|
func filtered(searchText: String) -> OfflineLibrarySnapshot {
|
|
guard let normalizedSearchText = OfflineLibrarySearch.normalizedQuery(from: searchText) else {
|
|
return self
|
|
}
|
|
|
|
return OfflineLibrarySnapshot(
|
|
remoteTracks: remoteTracks.filter { $0.matchesSearchQuery(normalizedSearchText) },
|
|
availableTracks: availableTracks.filter { $0.matchesSearchQuery(normalizedSearchText) }
|
|
)
|
|
}
|
|
}
|
|
|
|
private enum OfflineLibrarySearch {
|
|
static func normalizedQuery(from searchText: String) -> String? {
|
|
let trimmedQuery = searchText.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
guard !trimmedQuery.isEmpty else {
|
|
return nil
|
|
}
|
|
|
|
return normalize(trimmedQuery)
|
|
}
|
|
|
|
static func normalize(_ value: String) -> String {
|
|
value
|
|
.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
.folding(options: [.caseInsensitive, .diacriticInsensitive], locale: .current)
|
|
}
|
|
}
|
|
|
|
private extension OfflineLibraryRemoteTrack {
|
|
func matchesSearchQuery(_ query: String) -> Bool {
|
|
OfflineLibrarySearch.normalize(remoteTrack.title).contains(query)
|
|
|| OfflineLibrarySearch.normalize(remoteTrack.artist).contains(query)
|
|
}
|
|
}
|
|
|
|
private extension OfflineLibraryTrack {
|
|
func matchesSearchQuery(_ query: String) -> Bool {
|
|
OfflineLibrarySearch.normalize(title).contains(query)
|
|
|| OfflineLibrarySearch.normalize(artist).contains(query)
|
|
}
|
|
}
|