// // OperationCompletion.swift // Operations // // Created by pronebird on 24/01/2022. // Copyright © 2022 Mullvad VPN AB. All rights reserved. // import Foundation public enum OperationCompletion { case cancelled case success(Success) case failure(Failure) public var isSuccess: Bool { if case .success = self { return true } else { return false } } public var value: Success? { if case let .success(value) = self { return value } else { return nil } } public var error: Failure? { if case let .failure(error) = self { return error } else { return nil } } public var result: Result? { switch self { case let .success(value): return .success(value) case let .failure(error): return .failure(error) case .cancelled: return nil } } public init(result: Result) { switch result { case let .success(value): self = .success(value) case let .failure(error): self = .failure(error) } } public init(error: Failure?) where Success == Void { if let error = error { self = .failure(error) } else { self = .success(()) } } public func get() throws -> Success { if let result = result { return try result.get() } else { throw OperationCancellationError() } } public func map(_ block: (Success) -> NewSuccess) -> OperationCompletion { switch self { case let .success(value): return .success(block(value)) case let .failure(error): return .failure(error) case .cancelled: return .cancelled } } public func mapError(_ block: (Failure) -> NewFailure) -> OperationCompletion { switch self { case let .success(value): return .success(value) case let .failure(error): return .failure(block(error)) case .cancelled: return .cancelled } } public func flatMap(_ block: (Success) -> OperationCompletion) -> OperationCompletion { switch self { case let .success(value): return block(value) case let .failure(error): return .failure(error) case .cancelled: return .cancelled } } public func flatMapError( _ block: (Failure) -> OperationCompletion ) -> OperationCompletion { switch self { case let .success(value): return .success(value) case let .failure(error): return block(error) case .cancelled: return .cancelled } } public func tryMap(_ block: (Success) throws -> NewSuccess) -> OperationCompletion { switch self { case let .success(value): do { return .success(try block(value)) } catch { return .failure(error) } case let .failure(error): return .failure(error) case .cancelled: return .cancelled } } public func ignoreOutput() -> OperationCompletion { return map { _ in () } } public func eraseFailureType() -> OperationCompletion { return mapError { $0 } } } public struct OperationCancellationError: LocalizedError { public var errorDescription: String? { return "Operation was cancelled." } }