From 0ab52d2f43843ed6028f3586f6d4b6bf7594b1f7 Mon Sep 17 00:00:00 2001 From: John Estropia Date: Sat, 30 Mar 2019 23:58:26 +0900 Subject: [PATCH] converted *Result types to new Swift.Result --- Sources/AsynchronousDataTransaction.swift | 42 +---- Sources/CSMigrationResult.swift | 6 +- Sources/CSSetupResult.swift | 2 +- ...reStore+CustomDebugStringConvertible.swift | 163 ++++++------------ Sources/CoreStore+Transaction.swift | 2 +- Sources/DataStack+Migration.swift | 52 +++--- Sources/DataStack+Transaction.swift | 6 +- Sources/MigrationResult.swift | 47 +---- Sources/SetupResult.swift | 96 +---------- 9 files changed, 100 insertions(+), 316 deletions(-) diff --git a/Sources/AsynchronousDataTransaction.swift b/Sources/AsynchronousDataTransaction.swift index d0427b7..3767b8e 100644 --- a/Sources/AsynchronousDataTransaction.swift +++ b/Sources/AsynchronousDataTransaction.swift @@ -50,45 +50,11 @@ public final class AsynchronousDataTransaction: BaseDataTransaction { // MARK: - Result /** - The `Result` contains the success or failure information for a completed transaction + The `Result` contains the success or failure information for a completed transaction. + `Result.success` indicates that the transaction succeeded, either because the save succeeded or because there were no changes to save. The associated `userInfo` is the value returned from the transaction closure. + `Result.failure` indicates that the transaction either failed or was cancelled. The associated object for this value is a `CoreStoreError` enum value. */ - public enum Result { - - /** - `Result.success` indicates that the transaction succeeded, either because the save succeeded or because there were no changes to save. The associated `userInfo` is the value returned from the transaction closure. - */ - case success(userInfo: T) - - /** - `Result.failure` indicates that the transaction either failed or was cancelled. The associated object for this value is a `CoreStoreError` enum value. - */ - case failure(error: CoreStoreError) - - /** - Returns `true` if the result indicates `.success`, `false` if the result is `.failure`. - */ - public var boolValue: Bool { - - switch self { - - case .success: return true - case .failure: return false - } - } - - - // MARK: Internal - - internal init(userInfo: T) { - - self = .success(userInfo: userInfo) - } - - internal init(error: CoreStoreError) { - - self = .failure(error: error) - } - } + public typealias Result = Swift.Result // MARK: - diff --git a/Sources/CSMigrationResult.swift b/Sources/CSMigrationResult.swift index 54d29e6..8baca2b 100644 --- a/Sources/CSMigrationResult.swift +++ b/Sources/CSMigrationResult.swift @@ -43,7 +43,7 @@ public final class CSMigrationResult: NSObject, CoreStoreObjectiveCType { @objc public var isSuccess: Bool { - return self.bridgeToSwift.isSuccess + return (try? self.bridgeToSwift.get()) != nil } /** @@ -52,7 +52,7 @@ public final class CSMigrationResult: NSObject, CoreStoreObjectiveCType { @objc public var isFailure: Bool { - return !self.bridgeToSwift.isSuccess + return !self.isSuccess } /** @@ -173,7 +173,7 @@ public final class CSMigrationResult: NSObject, CoreStoreObjectiveCType { // MARK: - MigrationResult -extension MigrationResult: CoreStoreSwiftType { +extension MigrationResult { // MARK: CoreStoreSwiftType diff --git a/Sources/CSSetupResult.swift b/Sources/CSSetupResult.swift index 9475ad9..f4a32a9 100644 --- a/Sources/CSSetupResult.swift +++ b/Sources/CSSetupResult.swift @@ -177,7 +177,7 @@ public final class CSSetupResult: NSObject { // MARK: - SetupResult -extension SetupResult where T: CoreStoreSwiftType, T.ObjectiveCType: CSStorageInterface { +extension SetupResult where Success: StorageInterface, Success: CoreStoreSwiftType, Success.ObjectiveCType: CSStorageInterface, Failure == CoreStoreError { // MARK: CoreStoreSwiftType diff --git a/Sources/CoreStore+CustomDebugStringConvertible.swift b/Sources/CoreStore+CustomDebugStringConvertible.swift index 42ba499..00d923b 100644 --- a/Sources/CoreStore+CustomDebugStringConvertible.swift +++ b/Sources/CoreStore+CustomDebugStringConvertible.swift @@ -403,9 +403,16 @@ extension UnsafeDataModelSchema: CustomDebugStringConvertible, CoreStoreDebugStr // MARK: - ListMonitor @available(macOS 10.12, *) -private struct CoreStoreFetchedSectionInfoWrapper: CoreStoreDebugStringConvertible { +fileprivate struct CoreStoreFetchedSectionInfoWrapper: CoreStoreDebugStringConvertible { - let sectionInfo: NSFetchedResultsSectionInfo + // MARK: CustomDebugStringConvertible + + var debugDescription: String { + + return formattedDebugDescription(self) + } + + // MARK: CoreStoreDebugStringConvertible var coreStoreDumpString: String { @@ -415,6 +422,10 @@ private struct CoreStoreFetchedSectionInfoWrapper: CoreStoreDebugStringConvertib ("indexTitle", self.sectionInfo.indexTitle as Any) ) } + + // MARK: FilePrivate + + let sectionInfo: NSFetchedResultsSectionInfo } @available(macOS 10.12, *) @@ -546,41 +557,7 @@ extension MigrationChain: CustomDebugStringConvertible, CoreStoreDebugStringConv // MARK: - MigrationType -extension MigrationResult: CustomDebugStringConvertible, CoreStoreDebugStringConvertible { - - // MARK: CustomDebugStringConvertible - - public var debugDescription: String { - - return formattedDebugDescription(self) - } - - - // MARK: CoreStoreDebugStringConvertible - - public var coreStoreDumpString: String { - - switch self { - - case .success(let migrationTypes): - return createFormattedString( - ".success (", ")", - ("migrationTypes", migrationTypes) - ) - - case .failure(let error): - return createFormattedString( - ".failure (", ")", - ("error", error) - ) - } - } -} - - -// MARK: - MigrationType - -extension MigrationType: CustomDebugStringConvertible, CoreStoreDebugStringConvertible { +extension MigrationType: CoreStoreDebugStringConvertible { // MARK: CustomDebugStringConvertible @@ -683,41 +660,6 @@ extension PartialObject: CustomDebugStringConvertible, CoreStoreDebugStringConve } -// MARK: - SaveResult - -@available(*, deprecated, message: "Use the new DataStack.perform(asynchronous:...) and DataStack.perform(synchronous:...) family of APIs") -extension SaveResult: CustomDebugStringConvertible, CoreStoreDebugStringConvertible { - - // MARK: CustomDebugStringConvertible - - public var debugDescription: String { - - return formattedDebugDescription(self) - } - - - // MARK: CoreStoreDebugStringConvertible - - public var coreStoreDumpString: String { - - switch self { - - case .success(let hasChanges): - return createFormattedString( - ".success (", ")", - ("hasChanges", hasChanges) - ) - - case .failure(let error): - return createFormattedString( - ".failure (", ")", - ("error", error) - ) - } - } -} - - // MARK: - SectionBy @available(macOS 10.12, *) @@ -837,40 +779,6 @@ extension SelectTerm: CustomDebugStringConvertible, CoreStoreDebugStringConverti } -// MARK: - SetupResult - -extension SetupResult: CustomDebugStringConvertible, CoreStoreDebugStringConvertible { - - // MARK: CustomDebugStringConvertible - - public var debugDescription: String { - - return formattedDebugDescription(self) - } - - - // MARK: CoreStoreDebugStringConvertible - - public var coreStoreDumpString: String { - - switch self { - - case .success(let storage): - return createFormattedString( - ".success (", ")", - ("storage", storage) - ) - - case .failure(let error): - return createFormattedString( - ".failure (", ")", - ("error", error) - ) - } - } -} - - // MARK: - SQLiteStore extension SQLiteStore: CustomDebugStringConvertible, CoreStoreDebugStringConvertible { @@ -1132,7 +1040,7 @@ extension String { // MARK: - Private: CoreStoreDebugStringConvertible -public protocol CoreStoreDebugStringConvertible { +public protocol CoreStoreDebugStringConvertible: CustomDebugStringConvertible { var coreStoreDumpString: String { get } } @@ -1213,6 +1121,11 @@ extension NSAttributeDescription: CoreStoreDebugStringConvertible { extension NSAttributeType: CoreStoreDebugStringConvertible { + public var debugDescription: String { + + return formattedDebugDescription(self) + } + public var coreStoreDumpString: String { switch self { @@ -1248,6 +1161,11 @@ extension Bundle: CoreStoreDebugStringConvertible { extension NSDeleteRule: CoreStoreDebugStringConvertible { + public var debugDescription: String { + + return formattedDebugDescription(self) + } + public var coreStoreDumpString: String { switch self { @@ -1420,8 +1338,39 @@ extension Optional: CoreStoreDebugStringConvertible { } } +extension Result: CoreStoreDebugStringConvertible { + + public var debugDescription: String { + + return formattedDebugDescription(self) + } + + public var coreStoreDumpString: String { + + switch self { + + case .success(let info): + return createFormattedString( + ".success (", ")", + ("info", info) + ) + + case .failure(let error): + return createFormattedString( + ".failure (", ")", + ("error", error) + ) + } + } +} + extension Selector: CoreStoreDebugStringConvertible { + public var debugDescription: String { + + return formattedDebugDescription(self) + } + public var coreStoreDumpString: String { return "\"\(self)\"" diff --git a/Sources/CoreStore+Transaction.swift b/Sources/CoreStore+Transaction.swift index 8f8f3ae..a784ec9 100644 --- a/Sources/CoreStore+Transaction.swift +++ b/Sources/CoreStore+Transaction.swift @@ -31,7 +31,7 @@ import Foundation extension CoreStore { /** - Using the `defaultStack`, performs a transaction asynchronously where `NSManagedObject` or `CoreStoreObject` creates, updates, and deletes can be made. The changes are commited automatically after the `task` closure returns. On success, the value returned from closure will be the wrapped as `.success(userInfo: T)` in the `completion`'s `Result`. Any errors thrown from inside the `task` will be reported as `.failure(error: CoreStoreError)`. To cancel/rollback changes, call `try transaction.cancel()`, which throws a `CoreStoreError.userCancelled`. + Using the `defaultStack`, performs a transaction asynchronously where `NSManagedObject` or `CoreStoreObject` creates, updates, and deletes can be made. The changes are commited automatically after the `task` closure returns. On success, the value returned from closure will be the wrapped as `.success(T)` in the `completion`'s `Result`. Any errors thrown from inside the `task` will be reported as `.failure(CoreStoreError)`. To cancel/rollback changes, call `try transaction.cancel()`, which throws a `CoreStoreError.userCancelled`. - parameter task: the asynchronous closure where creates, updates, and deletes can be made to the transaction. Transaction blocks are executed serially in a background queue, and all changes are made from a concurrent `NSManagedObjectContext`. - parameter completion: the closure executed after the save completes. The `Result` argument of the closure will either wrap the return value of `task`, or any uncaught errors thrown from within `task`. Cancelled `task`s will be indicated by `.failure(error: CoreStoreError.userCancelled)`. Custom errors thrown by the user will be wrapped in `CoreStoreError.userError(error: Error)`. diff --git a/Sources/DataStack+Migration.swift b/Sources/DataStack+Migration.swift index f2c1434..bda75e1 100644 --- a/Sources/DataStack+Migration.swift +++ b/Sources/DataStack+Migration.swift @@ -55,7 +55,7 @@ extension DataStack { DispatchQueue.main.async { - completion(SetupResult(storage)) + completion(.success(storage)) } return } @@ -70,7 +70,7 @@ extension DataStack { DispatchQueue.main.async { - completion(SetupResult(storage)) + completion(.success(storage)) } } catch { @@ -82,7 +82,7 @@ extension DataStack { ) DispatchQueue.main.async { - completion(SetupResult(storeError)) + completion(.failure(storeError)) } } } @@ -119,7 +119,7 @@ extension DataStack { DispatchQueue.main.async { - completion(SetupResult(storage)) + completion(.success(storage)) } return nil } @@ -131,7 +131,7 @@ extension DataStack { DispatchQueue.main.async { - completion(SetupResult(existingStorage)) + completion(.success(existingStorage)) } return nil } @@ -143,7 +143,7 @@ extension DataStack { ) DispatchQueue.main.async { - completion(SetupResult(error)) + completion(.failure(error)) } return nil } @@ -181,17 +181,17 @@ extension DataStack { DispatchQueue.main.async { - completion(SetupResult(storage)) + completion(.success(storage)) } } catch { - completion(SetupResult(error)) + completion(.failure(CoreStoreError(error))) } return } - completion(SetupResult(error)) + completion(.failure(CoreStoreError(error))) return } @@ -201,12 +201,12 @@ extension DataStack { DispatchQueue.main.async { - completion(SetupResult(storage)) + completion(.success(storage)) } } catch { - completion(SetupResult(error)) + completion(.failure(CoreStoreError(error))) } } ) @@ -220,14 +220,14 @@ extension DataStack { DispatchQueue.main.async { - completion(SetupResult(storage)) + completion(.success(storage)) } } catch { DispatchQueue.main.async { - completion(SetupResult(error)) + completion(.failure(CoreStoreError(error))) } } return nil @@ -241,7 +241,7 @@ extension DataStack { ) DispatchQueue.main.async { - completion(SetupResult(storeError)) + completion(.failure(storeError)) } return nil } @@ -284,7 +284,7 @@ extension DataStack { DispatchQueue.main.async { - completion(SetupResult(storage)) + completion(.success(storage)) } return } @@ -296,7 +296,7 @@ extension DataStack { DispatchQueue.main.async { - completion(SetupResult(existingStorage)) + completion(.success(existingStorage)) } return } @@ -308,7 +308,7 @@ extension DataStack { ) DispatchQueue.main.async { - completion(SetupResult(error)) + completion(.failure(error)) } return } @@ -328,7 +328,7 @@ extension DataStack { ) DispatchQueue.main.async { - completion(SetupResult(storage)) + completion(.success(storage)) } } catch let error as NSError where storage.cloudStorageOptions.contains(.recreateLocalStoreOnModelMismatch) && error.isCoreDataMigrationError { @@ -358,14 +358,14 @@ extension DataStack { DispatchQueue.main.async { - completion(SetupResult(storage)) + completion(.success(storage)) } } catch { DispatchQueue.main.async { - completion(SetupResult(error)) + completion(.failure(CoreStoreError(error))) } } } @@ -378,7 +378,7 @@ extension DataStack { ) DispatchQueue.main.async { - completion(SetupResult(storeError)) + completion(.failure(storeError)) } } } @@ -514,7 +514,7 @@ extension DataStack { DispatchQueue.main.async { - completion(MigrationResult(error)) + completion(.failure(error)) } return nil } @@ -524,7 +524,7 @@ extension DataStack { DispatchQueue.main.async { - completion(MigrationResult([])) + completion(.success([])) return } return nil @@ -538,7 +538,7 @@ extension DataStack { ) DispatchQueue.main.async { - completion(MigrationResult(error)) + completion(.failure(error)) } return nil } @@ -586,7 +586,7 @@ extension DataStack { migrationError, "Failed to migrate version model \"\(migrationType.sourceVersion)\" to version \"\(migrationType.destinationVersion)\"." ) - migrationResult = MigrationResult(migrationError) + migrationResult = .failure(migrationError) cancelled = true } } @@ -609,7 +609,7 @@ extension DataStack { DispatchQueue.main.async { progress.setProgressHandler(nil) - completion(migrationResult ?? MigrationResult(migrationTypes)) + completion(migrationResult ?? .success(migrationTypes)) return } } diff --git a/Sources/DataStack+Transaction.swift b/Sources/DataStack+Transaction.swift index 162a811..ab35ca6 100644 --- a/Sources/DataStack+Transaction.swift +++ b/Sources/DataStack+Transaction.swift @@ -32,7 +32,7 @@ import CoreData extension DataStack { /** - Performs a transaction asynchronously where `NSManagedObject` or `CoreStoreObject` creates, updates, and deletes can be made. The changes are commited automatically after the `task` closure returns. On success, the value returned from closure will be the wrapped as `.success(userInfo: T)` in the `completion`'s `Result`. Any errors thrown from inside the `task` will be reported as `.failure(error: CoreStoreError)`. To cancel/rollback changes, call `try transaction.cancel()`, which throws a `CoreStoreError.userCancelled`. + Performs a transaction asynchronously where `NSManagedObject` or `CoreStoreObject` creates, updates, and deletes can be made. The changes are commited automatically after the `task` closure returns. On success, the value returned from closure will be the wrapped as `.success(T)` in the `completion`'s `Result`. Any errors thrown from inside the `task` will be reported as `.failure(CoreStoreError)`. To cancel/rollback changes, call `try transaction.cancel()`, which throws a `CoreStoreError.userCancelled`. - parameter task: the asynchronous closure where creates, updates, and deletes can be made to the transaction. Transaction blocks are executed serially in a background queue, and all changes are made from a concurrent `NSManagedObjectContext`. - parameter completion: the closure executed after the save completes. The `Result` argument of the closure will either wrap the return value of `task`, or any uncaught errors thrown from within `task`. Cancelled `task`s will be indicated by `.failure(error: CoreStoreError.userCancelled)`. Custom errors thrown by the user will be wrapped in `CoreStoreError.userError(error: Error)`. @@ -41,8 +41,8 @@ extension DataStack { self.perform( asynchronous: task, - success: { completion(.init(userInfo: $0)) }, - failure: { completion(.init(error: $0)) } + success: { completion(.success($0)) }, + failure: { completion(.failure($0)) } ) } diff --git a/Sources/MigrationResult.swift b/Sources/MigrationResult.swift index b1bff03..b1da216 100644 --- a/Sources/MigrationResult.swift +++ b/Sources/MigrationResult.swift @@ -30,7 +30,8 @@ import Foundation /** The `MigrationResult` indicates the result of a migration. - The `MigrationResult` can be treated as a boolean: + `MigrationResult.success` indicates either the migration succeeded, or there were no migrations needed. The associated value is an array of `MigrationType`s reflecting the migration steps completed. + `MigrationResult.failure` indicates that the migration failed. The associated object for this value is the a `CoreStoreError` enum value. ``` CoreStore.upgradeStorageIfNeeded(SQLiteStorage(fileName: "data.sqlite")) { (result) in switch result { @@ -42,46 +43,4 @@ import Foundation } ``` */ -public enum MigrationResult: Hashable { - - /** - `MigrationResult.success` indicates either the migration succeeded, or there were no migrations needed. The associated value is an array of `MigrationType`s reflecting the migration steps completed. - */ - case success([MigrationType]) - - /** - `SaveResult.failure` indicates that the migration failed. The associated object for this value is the a `CoreStoreError` enum value. - */ - case failure(CoreStoreError) - - - /** - Returns `true` if the result indicates `.success`, `false` if the result is `.failure`. - */ - public var isSuccess: Bool { - - switch self { - - case .success: return true - case .failure: return false - } - } - - - // MARK: Internal - - internal init(_ migrationTypes: [MigrationType]) { - - self = .success(migrationTypes) - } - - internal init(_ error: CoreStoreError) { - - self = .failure(error) - } - - internal init(_ error: Error) { - - self = .failure(CoreStoreError(error)) - } -} +public typealias MigrationResult = Swift.Result<[MigrationType], CoreStoreError> diff --git a/Sources/SetupResult.swift b/Sources/SetupResult.swift index 2a83dbf..a93e7c5 100644 --- a/Sources/SetupResult.swift +++ b/Sources/SetupResult.swift @@ -31,21 +31,8 @@ import CoreData /** The `SetupResult` indicates the result of an asynchronous initialization of a persistent store. - The `SetupResult` can be treated as a boolean: - ``` - try! CoreStore.addStorage( - SQLiteStore(), - completion: { (result: SetupResult) -> Void in - if result { - // succeeded - } - else { - // failed - } - } - ) - ``` - or as an `enum`, where the resulting associated object can also be inspected: + `SetupResult.success` indicates that the storage setup succeeded. The associated object for this `enum` value is the related `StorageInterface` instance. + `SetupResult.failure` indicates that the storage setup failed. The associated object for this value is the related `CoreStoreError` enum value. ``` try! CoreStore.addStorage( SQLiteStore(), @@ -60,81 +47,4 @@ import CoreData ) ``` */ -public enum SetupResult: Hashable { - - /** - `SetupResult.success` indicates that the storage setup succeeded. The associated object for this `enum` value is the related `StorageInterface` instance. - */ - case success(T) - - /** - `SetupResult.failure` indicates that the storage setup failed. The associated object for this value is the related `CoreStoreError` enum value. - */ - case failure(CoreStoreError) - - - /** - Returns `true` if the result indicates `.success`, `false` if the result is `.failure`. - */ - public var isSuccess: Bool { - - switch self { - - case .success: return true - case .failure: return false - } - } - - - // MARK: Equatable - - public static func == (lhs: SetupResult, rhs: SetupResult) -> Bool { - - switch (lhs, rhs) { - - case (.success(let storage1), .success(let storage2)): - return storage1 === storage2 - - case (.failure(let error1), .failure(let error2)): - return error1 == error2 - - default: - return false - } - } - - - // MARK: Hashable - - public func hash(into hasher: inout Hasher) { - - switch self { - - case .success(let storage): - hasher.combine(true) - hasher.combine(ObjectIdentifier(storage)) - - case .failure(let error): - hasher.combine(false) - hasher.combine(error) - } - } - - - // MARK: Internal - - internal init(_ storage: T) { - - self = .success(storage) - } - - internal init(_ error: CoreStoreError) { - - self = .failure(error) - } - - internal init(_ error: Error) { - - self = .failure(CoreStoreError(error)) - } -} +public typealias SetupResult = Swift.Result where StorageInterfaceType: StorageInterface