gitbay/Issues/IssueCreateViewModel.swift
45 lines · 1312 bytes
1import Foundation
2import Observation
3
4/// `issue create <repo> --title <t> --file -`.
5@Observable
6@MainActor
7final class IssueCreateViewModel {
8
9 private(set) var working = false
10 private(set) var errorMessage: String?
11
12 private let client: GitbayClient
13 let repoPath: String
14
15 init(client: GitbayClient, repoPath: String) {
16 self.client = client
17 self.repoPath = repoPath
18 }
19
20 nonisolated private struct Created: Decodable, Sendable {
21 let number: Int64
22 }
23
24 /// Returns the new issue's number, or nil with `errorMessage` set.
25 func create(title: String, body: String) async -> Int64? {
26 working = true
27 errorMessage = nil
28 defer { working = false }
29 do {
30 var argv = ["issue", "create", repoPath, "--title", title]
31 var stdin: String?
32 if !body.isEmpty {
33 argv.append(contentsOf: ["--file", "-"])
34 stdin = body
35 }
36 let created = try await client.run(argv, stdin: stdin, as: Created.self)
37 return created?.number
38 } catch let error as GitbayError {
39 errorMessage = error.userFacingMessage
40 } catch {
41 errorMessage = GitbayError.transport(error).userFacingMessage
42 }
43 return nil
44 }
45}