mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-08-26 17:28:38 +09:00
124 lines
2.9 KiB
Swift
124 lines
2.9 KiB
Swift
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
import Foundation
|
|
|
|
/**
|
|
* Status results for a Cursor
|
|
*/
|
|
public enum CursorStatus {
|
|
case success
|
|
case failure
|
|
case closed
|
|
}
|
|
|
|
public protocol TypedCursor: Sequence {
|
|
associatedtype T
|
|
var count: Int { get }
|
|
var status: CursorStatus { get }
|
|
var statusMessage: String { get }
|
|
subscript(index: Int) -> T? { get }
|
|
func asArray() -> [T]
|
|
}
|
|
|
|
/**
|
|
* Provides a generic method of returning some data and status information about a request.
|
|
*/
|
|
open class Cursor<T>: TypedCursor {
|
|
open var count: Int {
|
|
get { return 0 }
|
|
}
|
|
|
|
// Extra status information
|
|
open var status: CursorStatus
|
|
public var statusMessage: String
|
|
|
|
init(err: NSError) {
|
|
self.status = .failure
|
|
self.statusMessage = err.description
|
|
}
|
|
|
|
public init(status: CursorStatus = .success, msg: String = "") {
|
|
self.statusMessage = msg
|
|
self.status = status
|
|
}
|
|
|
|
// Collection iteration and access functions
|
|
open subscript(index: Int) -> T? {
|
|
get { return nil }
|
|
}
|
|
|
|
open func asArray() -> [T] {
|
|
var acc = [T]()
|
|
acc.reserveCapacity(self.count)
|
|
for row in self {
|
|
// Shouldn't ever be nil -- that's to allow the generator or subscript to be
|
|
// out of range.
|
|
if let row = row {
|
|
acc.append(row)
|
|
}
|
|
}
|
|
return acc
|
|
}
|
|
|
|
open func makeIterator() -> AnyIterator<T?> {
|
|
var nextIndex = 0
|
|
return AnyIterator() {
|
|
if nextIndex >= self.count || self.status != CursorStatus.success {
|
|
return nil
|
|
}
|
|
|
|
defer { nextIndex += 1 }
|
|
return self[nextIndex]
|
|
}
|
|
}
|
|
|
|
open func close() {
|
|
status = .closed
|
|
statusMessage = "Closed"
|
|
}
|
|
|
|
deinit {
|
|
if status != CursorStatus.closed {
|
|
close()
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* A cursor implementation that wraps an array.
|
|
*/
|
|
open class ArrayCursor<T> : Cursor<T> {
|
|
fileprivate var data: [T]
|
|
|
|
open override var count: Int {
|
|
if status != .success {
|
|
return 0
|
|
}
|
|
return data.count
|
|
}
|
|
|
|
public init(data: [T], status: CursorStatus, statusMessage: String) {
|
|
self.data = data
|
|
super.init(status: status, msg: statusMessage)
|
|
}
|
|
|
|
public convenience init(data: [T]) {
|
|
self.init(data: data, status: CursorStatus.success, statusMessage: "Success")
|
|
}
|
|
|
|
open override subscript(index: Int) -> T? {
|
|
get {
|
|
if index >= data.count || index < 0 || status != .success {
|
|
return nil
|
|
}
|
|
return data[index]
|
|
}
|
|
}
|
|
|
|
override open func close() {
|
|
data = [T]()
|
|
super.close()
|
|
}
|
|
}
|