mirror of https://github.com/oxen-io/session-ios
mirror of https://github.com/oxen-io/session-ios
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
54 lines
1.6 KiB
54 lines
1.6 KiB
// |
|
// Copyright (c) 2019 Open Whisper Systems. All rights reserved. |
|
// |
|
|
|
import Foundation |
|
|
|
// ObjC compatible searcher |
|
@objc class AnySearcher: NSObject { |
|
private let searcher: Searcher<AnyObject> |
|
|
|
public init(indexer: @escaping (AnyObject) -> String ) { |
|
searcher = Searcher(indexer: indexer) |
|
super.init() |
|
} |
|
|
|
@objc(item:doesMatchQuery:) |
|
public func matches(item: AnyObject, query: String) -> Bool { |
|
return searcher.matches(item: item, query: query) |
|
} |
|
} |
|
|
|
// A generic searching class, configurable with an indexing block |
|
public class Searcher<T> { |
|
|
|
private let indexer: (T) -> String |
|
|
|
public init(indexer: @escaping (T) -> String) { |
|
self.indexer = indexer |
|
} |
|
|
|
public func matches(item: T, query: String) -> Bool { |
|
let itemString = normalize(string: indexer(item)) |
|
return stem(string: query).map { queryStem in |
|
return itemString.contains(queryStem) |
|
}.reduce(true) { $0 && $1 } |
|
} |
|
|
|
private func stem(string: String) -> [String] { |
|
var normalized = normalize(string: string) |
|
|
|
// Remove any phone number formatting from the search terms |
|
let nonformattingScalars = normalized.unicodeScalars.lazy.filter { |
|
!CharacterSet.punctuationCharacters.contains($0) |
|
} |
|
|
|
normalized = String(String.UnicodeScalarView(nonformattingScalars)) |
|
|
|
return normalized.components(separatedBy: .whitespacesAndNewlines) |
|
} |
|
|
|
private func normalize(string: String) -> String { |
|
return string.lowercased().trimmingCharacters(in: .whitespacesAndNewlines) |
|
} |
|
}
|
|
|