Add searchable instrument browser

This commit is contained in:
diyaa
2026-09-14 00:55:41 +02:00
parent b2bf04e78b
commit ecbf07d1ea
5 changed files with 102 additions and 1 deletions
@@ -1,3 +1,5 @@
import Foundation
public struct LocalInstrumentCatalog: Sendable {
public let items: [InstrumentCatalogItem]
@@ -5,6 +7,18 @@ public struct LocalInstrumentCatalog: Sendable {
self.items = items
}
public func instruments(matching query: String) -> [InstrumentCatalogItem] {
let searchTokens = Self.searchTokens(for: query)
return items
.filter { item in
searchTokens.isEmpty || searchTokens.allSatisfy { token in
Self.searchableTerms(for: item).contains { $0.contains(token) }
}
}
.sorted { $0.name.localizedCaseInsensitiveCompare($1.name) == .orderedAscending }
}
public static let worldwideItems: [InstrumentCatalogItem] =
western + middleEastern + african + southAsian + eastAsian + southeastAsian + latinAmerican + folkAndModern
@@ -281,4 +295,23 @@ public struct LocalInstrumentCatalog: Sendable {
searchTerms: terms
)
}
private static func searchableTerms(for item: InstrumentCatalogItem) -> [String] {
searchTokens(for: [item.name] + item.aliases + item.searchTerms)
}
private static func searchTokens(for query: String) -> [String] {
searchTokens(for: [query])
}
private static func searchTokens(for values: [String]) -> [String] {
values
.joined(separator: " ")
.folding(
options: [.caseInsensitive, .diacriticInsensitive, .widthInsensitive],
locale: Locale(identifier: "en_US_POSIX")
)
.split(whereSeparator: { $0.isWhitespace || $0 == "-" })
.map(String.init)
}
}