gitbay/MRs/MRFilter.swift

v1.14.1
gitbay-ios/gitbay/MRs/MRFilter.swift history · blame · raw

49 lines · 1540 bytes

 1import Foundation
 2
 3/// What `mr list` is narrowed to. The command takes no `--assignee`, so
 4/// this offers none.
 5nonisolated struct MRFilter: Equatable, Sendable {
 6
 7    enum State: String, CaseIterable, Identifiable, Sendable {
 8        case open, merged, closed
 9        case sourceGone = "source_gone"
10        case all
11
12        var id: String { rawValue }
13        var label: String { stateLabel(rawValue) }
14    }
15
16    var state: State = .open
17    var search = ""
18    var label: String?
19    var author: String?
20    var milestone: String?
21
22    func flags() -> [String] {
23        var flags = ["--state", state.rawValue]
24        flags += filterFlag("--search", search)
25        flags += filterFlag("--label", label)
26        flags += filterFlag("--author", author)
27        flags += filterFlag("--milestone", milestone)
28        return flags
29    }
30
31    var isNarrowed: Bool { flags().count > 2 }
32
33    var emptyMessage: String {
34        let noun = "merge requests"
35        if isNarrowed {
36            return state == .all
37                ? "No \(noun) match these filters."
38                : "No \(state.label.lowercased()) \(noun) match these filters."
39        }
40        return state == .all ? "No \(noun)." : "No \(state.label.lowercased()) \(noun)."
41    }
42}
43
44/// A wire state (`open`, `source_gone`) as the app shows it: sentence
45/// case, underscores as spaces.
46nonisolated func stateLabel(_ state: String) -> String {
47    let words = state.replacingOccurrences(of: "_", with: " ")
48    return words.prefix(1).uppercased() + words.dropFirst()
49}