Commit.swift 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. //
  2. // Commit.swift
  3. // FLEXample
  4. //
  5. // Created by Tanner on 3/12/20.
  6. // Copyright © 2020 Flipboard. All rights reserved.
  7. //
  8. import Foundation
  9. infix operator ~ : ComparisonPrecedence
  10. func ~ (a: String, b: String) -> Bool {
  11. return a.localizedCaseInsensitiveContains(b)
  12. }
  13. func ~ (a: NSString, b: String) -> Bool {
  14. return a.localizedCaseInsensitiveContains(b)
  15. }
  16. /// Used for both commit details and the outer committer
  17. @objcMembers
  18. public class CommitIdentity: NSObject, Codable {
  19. // These actually come from the "root[committer]" part
  20. public let login: String?
  21. public let id: Int?
  22. public let avatarUrl: String?
  23. public let gravatarUrl: String?
  24. // These actually come from the
  25. // "root[commit][author/committer]" part
  26. public let name: String?
  27. public let email: String?
  28. public let date: Date?
  29. public func matches(query: String) -> Bool {
  30. if let login = self.login {
  31. return login ~ query
  32. } else if let name = self.name, let email = self.email {
  33. return name ~ query || email ~ query
  34. }
  35. return false
  36. }
  37. }
  38. @objcMembers
  39. public class CommitDetails: NSObject, Codable {
  40. public let message: String
  41. public let url: String
  42. public let author: CommitIdentity
  43. public let committer: CommitIdentity
  44. public func matches(query: String) -> Bool {
  45. return message ~ query ||
  46. author.matches(query: query) ||
  47. committer.matches(query: query)
  48. }
  49. }
  50. @objcMembers
  51. public class Commit: NSObject, Codable {
  52. static var formatter: DateFormatter = {
  53. var f = DateFormatter()
  54. f.dateFormat = "dd MMM yyyy h:mm a"
  55. return f
  56. }()
  57. /// Turn some response data into a list of commits
  58. static func commits(from data: Data) -> [Commit] {
  59. let decoder = JSONDecoder()
  60. decoder.keyDecodingStrategy = .convertFromSnakeCase
  61. decoder.dateDecodingStrategy = .iso8601
  62. _ = try! decoder.decode([Commit].self, from: data)
  63. if let commits = try? decoder.decode([Commit].self, from: data) {
  64. return commits
  65. }
  66. return []
  67. }
  68. enum CodingKeys: String, CodingKey {
  69. case sha, htmlUrl, committer
  70. case details = "commit"
  71. }
  72. public private(set) var sha: String = ""
  73. public private(set) var htmlUrl: String = ""
  74. /// Details does not contain avi URLs for users
  75. public private(set) var details: CommitDetails
  76. /// This does have the (g)avatar URL
  77. public private(set) var committer: CommitIdentity
  78. public func matches(query: String) -> Bool {
  79. return sha ~ query ||
  80. details.matches(query: query) ||
  81. committer.matches(query: query)
  82. }
  83. // You're crazy if you think I'm going to slice strings with Swift.String
  84. public lazy var shortHash: String = NSString(string: self.sha).substring(to: 8)
  85. public lazy var date: String = {
  86. if let date = details.committer.date ?? details.author.date {
  87. return Commit.formatter.string(from: date)
  88. }
  89. return "no date found"
  90. }()
  91. public lazy var firstLine: String = {
  92. let name = details.committer.name ?? details.author.name ?? "Anonymous"
  93. return name + " — " + self.date
  94. }()
  95. public lazy var secondLine: String = {
  96. return self.shortHash + " " + self.details.message
  97. }()
  98. public lazy var identifier: Int = self.sha.hashValue
  99. }