gitbay/MRs/MRFilter.swift
49 lines · 1540 bytes
3 symbols in this file
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}