124 lines
3.4 KiB
Swift
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
|
|
}
|