Files
GitHawk/Classes/Utility/SearchQueryTokenizer.swift
2018-04-07 23:24:51 -04:00

54 lines
1.8 KiB
Swift

//
// SearchQueryTokenizer.swift
// Freetime
//
// Created by Weyert de Boer on 09/10/2017.
// Copyright © 2017 Ryan Nystrom. All rights reserved.
//
struct SearchQueryParseResults {
let tokens: [Token]
let leftover: String
}
enum TokenAction: String {
case status = "is"
case user = "user"
}
typealias Token = (action: TokenAction, value: String)
/// Tokenizes a search query and returns an instance of ParseResult which consists
/// of all the found "search tokens" such as `is:closed` and separately returns
/// the text of the search query which isn't part of any search token
func tokenizeSearchQuery(_ query: String) -> SearchQueryParseResults {
let chunks = query.components(separatedBy: " ")
var leftover: String = query
let tokens: [Token] = chunks.compactMap { chunk -> Token? in
let chunk = chunk.trimmingCharacters(in: .whitespacesAndNewlines)
let valueChunks = chunk.components(separatedBy: ":")
guard !valueChunks.isEmpty else { return nil }
if valueChunks.count == 2, let action = valueChunks.first, let tokenValue = valueChunks.last {
guard let tokenAction = TokenAction(rawValue: action.lowercased()) else { return nil }
leftover = leftover.replacingOccurrences(of: chunk, with: "")
return Token(tokenAction, tokenValue)
}
return nil
}
let trimmedLeftover = leftover.trimmingCharacters(in: .whitespacesAndNewlines)
return SearchQueryParseResults(tokens: tokens, leftover: trimmedLeftover)
}
func isIssueStatus(status: IssueStatus, text: String) -> Bool {
let text = text.trimmingCharacters(in: .whitespacesAndNewlines).lowercased()
switch status {
case .open: return text == "open"
case .closed: return text == "closed"
case .merged: return text == "merged"
}
}