gitbay/Issues/IssueModels.swift
72 lines · 2376 bytes
3 symbols in this file
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}