gitbay/MRs/MRModels.swift

5411753023a5e2958f17b523903abce380941107
gitbay-ios/gitbay/MRs/MRModels.swift history · blame · raw

121 lines · 3522 bytes

  1import Foundation
  2
  3/// One row of `mr list`, and the header half of `mr show`.
  4nonisolated struct MergeRequest: Decodable, Sendable, Hashable, Identifiable {
  5    let number: Int64
  6    let title: String
  7    let state: String
  8    let author: String
  9    /// "branch" for a same-repo MR, "owner/name:branch" cross-repo,
 10    /// "" when the source is gone.
 11    let source: String
 12    let targetRef: String
 13    let headSHA: String
 14    let body: String?
 15    let createdAt: Date
 16
 17    enum CodingKeys: String, CodingKey {
 18        case number, title, state, author, source, body
 19        case targetRef = "target_ref"
 20        case headSHA = "head_sha"
 21        case createdAt = "created_at"
 22    }
 23
 24    var id: Int64 { number }
 25    var isOpen: Bool { state == "open" }
 26}
 27
 28/// The whole of `mr show`.
 29nonisolated struct MRDetail: Decodable, Sendable, Hashable {
 30    let number: Int64
 31    let title: String
 32    let state: String
 33    let author: String
 34    let source: String
 35    let targetRef: String
 36    let headSHA: String
 37    let body: String?
 38    let createdAt: Date
 39    let checks: [Check]?
 40    let checksCombined: String?
 41    let unresolvedThreads: Int?
 42    let commits: [MRCommit]?
 43    let comments: [MRComment]?
 44    let reviews: [Review]?
 45
 46    enum CodingKeys: String, CodingKey {
 47        case number, title, state, author, source, body, checks, commits, comments, reviews
 48        case targetRef = "target_ref"
 49        case headSHA = "head_sha"
 50        case createdAt = "created_at"
 51        case checksCombined = "checks_combined"
 52        case unresolvedThreads = "unresolved_threads"
 53    }
 54
 55    var isOpen: Bool { state == "open" }
 56
 57    nonisolated struct Check: Decodable, Sendable, Hashable {
 58        let context: String
 59        let state: String
 60        let url: String?
 61    }
 62
 63    nonisolated struct MRCommit: Decodable, Sendable, Hashable, Identifiable {
 64        let sha: String
 65        let subject: String
 66        var id: String { sha }
 67        var shortSHA: String { String(sha.prefix(10)) }
 68    }
 69
 70    nonisolated struct MRComment: Decodable, Sendable, Hashable, Identifiable {
 71        let author: String
 72        let body: String
 73        let createdAt: Date
 74
 75        enum CodingKeys: String, CodingKey {
 76            case author, body
 77            case createdAt = "created_at"
 78        }
 79
 80        var id: String { author + createdAt.timeIntervalSince1970.description + body }
 81    }
 82
 83    nonisolated struct Review: Decodable, Sendable, Hashable, Identifiable {
 84        let reviewer: String
 85        let verdict: String
 86        /// The review predates the current head — it approved older code.
 87        let stale: Bool
 88        var id: String { reviewer }
 89    }
 90}
 91
 92/// One review thread of `mr threads`.
 93nonisolated struct ReviewThread: Decodable, Sendable, Hashable, Identifiable {
 94    let id: Int64
 95    let path: String
 96    let side: String // new | old
 97    let line: Int64
 98    /// Anchored to an older head; the diff has moved under it.
 99    let stale: Bool
100    let resolvedBy: String?
101    let comments: [Comment]
102
103    enum CodingKeys: String, CodingKey {
104        case id, path, side, line, stale, comments
105        case resolvedBy = "resolved_by"
106    }
107
108    var isResolved: Bool { resolvedBy != nil }
109
110    nonisolated struct Comment: Decodable, Sendable, Hashable, Identifiable {
111        let id: Int64
112        let author: String
113        let body: String
114        let createdAt: Date
115
116        enum CodingKeys: String, CodingKey {
117            case id, author, body
118            case createdAt = "created_at"
119        }
120    }
121}