summaryrefslogtreecommitdiffhomepage
path: root/ios/Operations/OperationCompletion.swift
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2022-09-25 16:34:23 +0200
committerAndrej Mihajlov <and@mullvad.net>2022-09-26 16:35:38 +0200
commitf389956c2cd884df142adbf00ff2ac7e2f69c2b2 (patch)
tree5f7d4869324760eb4ba0107c0356edc89efd1457 /ios/Operations/OperationCompletion.swift
parent2e83b1ca27ff243a615ff10c94c20840b38dfd45 (diff)
downloadmullvadvpn-f389956c2cd884df142adbf00ff2ac7e2f69c2b2.tar.xz
mullvadvpn-f389956c2cd884df142adbf00ff2ac7e2f69c2b2.zip
Move AsyncOperation into Operations static library and add separate tests
Diffstat (limited to 'ios/Operations/OperationCompletion.swift')
-rw-r--r--ios/Operations/OperationCompletion.swift145
1 files changed, 145 insertions, 0 deletions
diff --git a/ios/Operations/OperationCompletion.swift b/ios/Operations/OperationCompletion.swift
new file mode 100644
index 0000000000..ffb8f54ce8
--- /dev/null
+++ b/ios/Operations/OperationCompletion.swift
@@ -0,0 +1,145 @@
+//
+// OperationCompletion.swift
+// MullvadVPN
+//
+// Created by pronebird on 24/01/2022.
+// Copyright © 2022 Mullvad VPN AB. All rights reserved.
+//
+
+import Foundation
+
+public enum OperationCompletion<Success, Failure: Error> {
+ 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<Success, Failure>? {
+ switch self {
+ case let .success(value):
+ return .success(value)
+ case let .failure(error):
+ return .failure(error)
+ case .cancelled:
+ return nil
+ }
+ }
+
+ public init(result: Result<Success, Failure>) {
+ 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 map<NewSuccess>(_ block: (Success) -> NewSuccess)
+ -> OperationCompletion<NewSuccess, Failure>
+ {
+ switch self {
+ case let .success(value):
+ return .success(block(value))
+ case let .failure(error):
+ return .failure(error)
+ case .cancelled:
+ return .cancelled
+ }
+ }
+
+ public func mapError<NewFailure: Error>(_ block: (Failure) -> NewFailure)
+ -> OperationCompletion<Success, NewFailure>
+ {
+ switch self {
+ case let .success(value):
+ return .success(value)
+ case let .failure(error):
+ return .failure(block(error))
+ case .cancelled:
+ return .cancelled
+ }
+ }
+
+ public func flatMap<NewSuccess>(_ block: (Success) -> OperationCompletion<NewSuccess, Failure>)
+ -> OperationCompletion<NewSuccess, Failure>
+ {
+ switch self {
+ case let .success(value):
+ return block(value)
+ case let .failure(error):
+ return .failure(error)
+ case .cancelled:
+ return .cancelled
+ }
+ }
+
+ public func flatMapError<NewFailure: Error>(
+ _ block: (Failure)
+ -> OperationCompletion<Success, NewFailure>
+ ) -> OperationCompletion<Success, NewFailure> {
+ switch self {
+ case let .success(value):
+ return .success(value)
+ case let .failure(error):
+ return block(error)
+ case .cancelled:
+ return .cancelled
+ }
+ }
+
+ public func tryMap<NewSuccess>(_ block: (Success) throws -> NewSuccess)
+ -> OperationCompletion<NewSuccess, Error>
+ {
+ 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<Void, Failure> {
+ return map { _ in () }
+ }
+
+ public func eraseFailureType() -> OperationCompletion<Success, Error> {
+ return mapError { $0 }
+ }
+}