gitbay/MRs/MRModels.swift

v1.0.4
gitbay-ios/gitbay/MRs/MRModels.swift history · blame · raw

149 lines · 4490 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 milestone: String?
 39    let createdAt: Date
 40    /// Set once the merge request is resolved. The actor is absent when
 41    /// the account is gone, or the row was imported.
 42    let mergedAt: Date?
 43    let mergedBy: String?
 44    let closedAt: Date?
 45    let closedBy: String?
 46    let checks: [Check]?
 47    let checksCombined: String?
 48    let unresolvedThreads: Int?
 49    let commits: [MRCommit]?
 50    let comments: [MRComment]?
 51    let reviews: [Review]?
 52
 53    enum CodingKeys: String, CodingKey {
 54        case number, title, state, author, source, body, milestone, checks, commits, comments, reviews
 55        case targetRef = "target_ref"
 56        case headSHA = "head_sha"
 57        case createdAt = "created_at"
 58        case mergedAt = "merged_at"
 59        case mergedBy = "merged_by"
 60        case closedAt = "closed_at"
 61        case closedBy = "closed_by"
 62        case checksCombined = "checks_combined"
 63        case unresolvedThreads = "unresolved_threads"
 64    }
 65
 66    var isOpen: Bool { state == "open" }
 67
 68    nonisolated struct Check: Decodable, Sendable, Hashable {
 69        let context: String
 70        let state: String
 71        let url: String?
 72        /// When the check last changed state.
 73        let updatedAt: Date?
 74        /// How long the build behind the check ran, as the server
 75        /// formats it ("1m12s"). Only CI checks have a build to time.
 76        let duration: String?
 77
 78        enum CodingKeys: String, CodingKey {
 79            case context, state, url, duration
 80            case updatedAt = "updated_at"
 81        }
 82    }
 83
 84    nonisolated struct MRCommit: Decodable, Sendable, Hashable, Identifiable {
 85        let sha: String
 86        let subject: String
 87        var id: String { sha }
 88        var shortSHA: String { String(sha.prefix(10)) }
 89    }
 90
 91    nonisolated struct MRComment: Decodable, Sendable, Hashable, Identifiable {
 92        let author: String
 93        let body: String
 94        let createdAt: Date
 95
 96        enum CodingKeys: String, CodingKey {
 97            case author, body
 98            case createdAt = "created_at"
 99        }
100
101        var id: String { author + createdAt.timeIntervalSince1970.description + body }
102    }
103
104    nonisolated struct Review: Decodable, Sendable, Hashable, Identifiable {
105        let reviewer: String
106        let verdict: String
107        /// The review predates the current head — it approved older code.
108        let stale: Bool
109        let createdAt: Date?
110
111        enum CodingKeys: String, CodingKey {
112            case reviewer, verdict, stale
113            case createdAt = "created_at"
114        }
115
116        var id: String { reviewer }
117    }
118}
119
120/// One review thread of `mr threads`.
121nonisolated struct ReviewThread: Decodable, Sendable, Hashable, Identifiable {
122    let id: Int64
123    let path: String
124    let side: String // new | old
125    let line: Int64
126    /// Anchored to an older head; the diff has moved under it.
127    let stale: Bool
128    let resolvedBy: String?
129    let comments: [Comment]
130
131    enum CodingKeys: String, CodingKey {
132        case id, path, side, line, stale, comments
133        case resolvedBy = "resolved_by"
134    }
135
136    var isResolved: Bool { resolvedBy != nil }
137
138    nonisolated struct Comment: Decodable, Sendable, Hashable, Identifiable {
139        let id: Int64
140        let author: String
141        let body: String
142        let createdAt: Date
143
144        enum CodingKeys: String, CodingKey {
145            case id, author, body
146            case createdAt = "created_at"
147        }
148    }
149}