import Foundation /// What `mr list` is narrowed to. The command takes no `--assignee`, so /// this offers none. nonisolated struct MRFilter: Equatable, Sendable { enum State: String, CaseIterable, Identifiable, Sendable { case open, merged, closed case sourceGone = "source_gone" case all var id: String { rawValue } /// Segment text. Five segments share a phone's width, so the /// source-gone state is one word; the rows and chips still say /// "source gone" in full. var label: String { self == .sourceGone ? "Gone" : rawValue.capitalized } } var state: State = .open var search = "" var label: String? var author: String? var milestone: String? func flags() -> [String] { var flags = ["--state", state.rawValue] flags += filterFlag("--search", search) flags += filterFlag("--label", label) flags += filterFlag("--author", author) flags += filterFlag("--milestone", milestone) return flags } var isNarrowed: Bool { flags().count > 2 } var emptyMessage: String { let noun = "merge requests" if isNarrowed { return state == .all ? "No \(noun) match these filters." : "No \(state.label.lowercased()) \(noun) match these filters." } return state == .all ? "No \(noun)." : "No \(state.label.lowercased()) \(noun)." } }