SwiftGit2/SwiftGit2/CommitIterator.swift
Arnon Keereena 8d1aaa672f Changing from using if to evaluates returned enum
to switch case syntax instead
2017-05-04 22:41:32 +02:00

143 lines
4.3 KiB
Swift

//
// Created by Arnon Keereena on 4/28/17.
// Copyright (c) 2017 GitHub, Inc. All rights reserved.
//
import Result
import libgit2
public class CommitIterator: IteratorProtocol, Sequence {
public typealias Iterator = CommitIterator
public typealias Element = Result<Commit, NSError>
let repo: Repository
private var revisionWalker: OpaquePointer? = nil
private enum Next {
case over
case ok
case error(NSError)
init(_ result: Int32, name: String) {
switch result {
case GIT_ITEROVER.rawValue:
self = .over
case GIT_OK.rawValue:
self = .ok
default:
self = .error(NSError(gitError: result, pointOfFailure: name))
}
}
}
init(repo: Repository, root: git_oid) {
self.repo = repo
setupRevisionWalker(root: root)
}
deinit {
git_revwalk_free(self.revisionWalker)
}
private func setupRevisionWalker(root: git_oid) {
var oid = root
git_revwalk_new(&revisionWalker, repo.pointer)
git_revwalk_sorting(revisionWalker, GIT_SORT_TOPOLOGICAL.rawValue)
git_revwalk_sorting(revisionWalker, GIT_SORT_TIME.rawValue)
git_revwalk_push(revisionWalker, &oid)
}
public func next() -> Element? {
var oid = git_oid()
let revwalkGitResult = git_revwalk_next(&oid, revisionWalker)
let nextResult = Next(revwalkGitResult, name: "git_revwalk_next")
switch nextResult {
case let .error(error):
return Result.failure(error)
case .over:
return nil
case .ok:
var unsafeCommit: OpaquePointer? = nil
let lookupGitResult = git_commit_lookup(&unsafeCommit, repo.pointer, &oid)
guard lookupGitResult == GIT_OK.rawValue,
let unwrapCommit = unsafeCommit else {
return Result.failure(NSError(gitError: lookupGitResult, pointOfFailure: "git_commit_lookup"))
}
let result: Element = Result.success(Commit(unwrapCommit))
git_commit_free(unsafeCommit)
return result
}
}
public func makeIterator() -> CommitIterator {
return self
}
public private(set) var underestimatedCount: Int = 0
public func map<T>(_ transform: (Result<Commit, NSError>) throws -> T) rethrows -> [T] {
var new: [T] = []
for item in self {
new = new + [try transform(item)]
}
return new
}
public func filter(_ isIncluded: (Result<Commit, NSError>) throws -> Bool) rethrows -> [Result<Commit, NSError>] {
var new: [Result<Commit, NSError>] = []
for item in self {
if try isIncluded(item) {
new = new + [item]
}
}
return new
}
public func forEach(_ body: (Result<Commit, NSError>) throws -> Void) rethrows {
for item in self {
try body(item)
}
}
private func notImplemented(functionName: Any) {
assert(false, "CommitIterator does not implement \(functionName)")
}
private init(repo: Repository) {
self.repo = repo
}
public func dropFirst(_ n: Int) -> AnySequence<Iterator.Element> {
notImplemented(functionName: self.dropFirst)
return AnySequence<Iterator.Element> { return CommitIterator(repo: self.repo) }
}
public func dropLast(_ n: Int) -> AnySequence<Iterator.Element> {
notImplemented(functionName: self.dropLast)
return AnySequence<Iterator.Element> { return CommitIterator(repo: self.repo) }
}
public func drop(while predicate: (Result<Commit, NSError>) throws -> Bool) rethrows -> AnySequence<Iterator.Element> {
notImplemented(functionName: self.drop)
return AnySequence<Iterator.Element> { return CommitIterator(repo: self.repo) }
}
public func prefix(_ maxLength: Int) -> AnySequence<Iterator.Element> {
notImplemented(functionName: "prefix(_ maxLength:")
return AnySequence<Iterator.Element> { return CommitIterator(repo: self.repo) }
}
public func prefix(while predicate: (Result<Commit, NSError>) throws -> Bool) rethrows -> AnySequence<Iterator.Element> {
notImplemented(functionName: "prefix(with predicate:")
return AnySequence<Iterator.Element> { return CommitIterator(repo: self.repo) }
}
public func suffix(_ maxLength: Int) -> AnySequence<Iterator.Element> {
notImplemented(functionName: self.suffix)
return AnySequence<Iterator.Element> { return CommitIterator(repo: self.repo) }
}
public func split(maxSplits: Int, omittingEmptySubsequences: Bool, whereSeparator isSeparator: (Result<Commit, NSError>) throws -> Bool) rethrows -> [AnySequence<Iterator.Element>] {
notImplemented(functionName: self.split)
return [AnySequence<Iterator.Element> { return CommitIterator(repo: self.repo) }]
}
}