gitbay/Issues/IssueModels.swift

v1.13.0
gitbay-ios/gitbay/Issues/IssueModels.swift history · blame · raw

72 lines · 2376 bytes

 1import Foundation
 2
 3/// One issue; `issue list` rows and the header of `issue show`.
 4nonisolated struct Issue: Decodable, Sendable, Hashable, Identifiable {
 5    let number: Int64
 6    let title: String
 7    let state: String
 8    let author: String
 9    let milestone: String?
10    let labels: [String]?
11    let assignees: [String]?
12    let body: String?
13    let createdAt: Date
14
15    enum CodingKeys: String, CodingKey {
16        case number, title, state, author, milestone, labels, assignees, body
17        case createdAt = "created_at"
18    }
19
20    var id: Int64 { number }
21    var isOpen: Bool { state == "open" }
22}
23
24/// `issue show <owner/name> <n>` — the issue plus its comments.
25nonisolated struct IssueDetail: Decodable, Sendable, Hashable {
26    let number: Int64
27    let title: String
28    let state: String
29    let author: String
30    let milestone: String?
31    let labels: [String]?
32    let assignees: [String]?
33    let body: String?
34    let bodyFormat: String?
35    let createdAt: Date
36    let reactions: [ReactionCount]?
37    let comments: [Comment]?
38
39    enum CodingKeys: String, CodingKey {
40        case number, title, state, author, milestone, labels, assignees, body, reactions, comments
41        case bodyFormat = "body_format"
42        case createdAt = "created_at"
43    }
44
45    var isOpen: Bool { state == "open" }
46
47    nonisolated struct Comment: Decodable, Sendable, Hashable, Identifiable {
48        /// What `--comment` names. Absent from a server older than v1.39.0.
49        let commentID: Int64?
50        let author: String
51        let body: String
52        let bodyFormat: String?
53        let createdAt: Date
54        let reactions: [ReactionCount]?
55        /// "system" for a line the server posted (a retarget, a queued
56        /// merge), which takes no reactions (krz/gitbay#332).
57        let kind: String?
58
59        enum CodingKeys: String, CodingKey {
60            case author, body, reactions, kind
61            case commentID = "id"
62            case bodyFormat = "body_format"
63            case createdAt = "created_at"
64        }
65
66        /// A server without `kind` names the author "system" on those lines;
67        /// an account can carry that name too, so `kind` wins when present.
68        var isSystem: Bool { kind.map { $0 == "system" } ?? (author == "system") }
69
70        var id: String { author + createdAt.timeIntervalSince1970.description + body }
71    }
72}