Files
2022-04-27 13:45:42 -05:00

124 lines
3.4 KiB
Swift

//
// Commit.swift
// FLEXample
//
// Created by Tanner on 3/12/20.
// Copyright © 2020 Flipboard. All rights reserved.
//
import Foundation
infix operator ~ : ComparisonPrecedence
func ~ (a: String, b: String) -> Bool {
return a.localizedCaseInsensitiveContains(b)
}
func ~ (a: NSString, b: String) -> Bool {
return a.localizedCaseInsensitiveContains(b)
}
/// Used for both commit details and the outer committer
@objcMembers
public class CommitIdentity: NSObject, Codable {
// These actually come from the "root[committer]" part
public let login: String?
public let id: Int?
public let avatarUrl: String?
public let gravatarUrl: String?
// These actually come from the
// "root[commit][author/committer]" part
public let name: String?
public let email: String?
public let date: Date?
public func matches(query: String) -> Bool {
if let login = self.login {
return login ~ query
} else if let name = self.name, let email = self.email {
return name ~ query || email ~ query
}
return false
}
}
//@objcMembers
public struct CommitDetails: Codable {
public let message: String
public let url: String
public let author: CommitIdentity
public let committer: CommitIdentity
public func matches(query: String) -> Bool {
return message ~ query ||
author.matches(query: query) ||
committer.matches(query: query)
}
}
@objcMembers
public class Commit: NSObject, Codable {
static var formatter: DateFormatter = {
var f = DateFormatter()
f.dateFormat = "dd MMM yyyy h:mm a"
return f
}()
/// Turn some response data into a list of commits
static func commits(from data: Data) -> [Commit] {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
decoder.dateDecodingStrategy = .iso8601
_ = try! decoder.decode([Commit].self, from: data)
if let commits = try? decoder.decode([Commit].self, from: data) {
return commits
}
return []
}
enum CodingKeys: String, CodingKey {
case sha, htmlUrl, committer
case details = "commit"
}
public private(set) var sha: String = ""
public private(set) var htmlUrl: String = ""
/// Details does not contain avi URLs for users
public private(set) var details: CommitDetails
/// This does have the (g)avatar URL
public private(set) var committer: CommitIdentity
public func matches(query: String) -> Bool {
return sha ~ query ||
details.matches(query: query) ||
committer.matches(query: query)
}
// You're crazy if you think I'm going to slice strings with Swift.String
public lazy var shortHash: String = NSString(string: self.sha).substring(to: 8)
public lazy var date: String = {
if let date = details.committer.date ?? details.author.date {
return Commit.formatter.string(from: date)
}
return "no date found"
}()
public lazy var firstLine: String = {
let name = details.committer.name ?? details.author.name ?? "Anonymous"
return name + "" + self.date
}()
public lazy var secondLine: String = {
return self.shortHash + " " + self.details.message
}()
public lazy var identifier: Int = self.sha.hashValue
}