Skip to content

Instantly share code, notes, and snippets.

@nalexn
Last active July 24, 2020 01:14
  • Star 0 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save nalexn/df65131de76301130c8e179d02cec939 to your computer and use it in GitHub Desktop.
A container for a resource requested from the backend
// Copyright © 2019 Alexey Naumov. MIT License
import Foundation
enum Loadable<Value> {
case notRequested
case isLoading(prevValue: Value?)
case loaded(Value)
case failed(Error)
}
extension Loadable {
var value: Value? {
switch self {
case .notRequested, .failed: return nil
case let .loaded(value): return value
case let .isLoading(value): return value
}
}
var error: Error? {
switch self {
case let .failed(error): return error
default: return nil
}
}
var isLoading: Bool {
switch self {
case .isLoading: return true
default: return false
}
}
var isLoaded: Bool {
switch self {
case .loaded: return true
default: return false
}
}
var isFailed: Bool {
switch self {
case .failed: return true
default: return false
}
}
}
extension Loadable: Equatable where Value: Equatable {
static func == (lhs: Loadable<Value>, rhs: Loadable<Value>) -> Bool {
switch (lhs, rhs) {
case (.notRequested, .notRequested):
return true
case let (.isLoading(lhsPrev), .isLoading(rhsPrev)):
return lhsPrev == rhsPrev
case let (.loaded(lhsValue), .loaded(rhsValue)):
return lhsValue == rhsValue
case let (.failed(lhsError), .failed(rhsError)):
return lhsError.localizedDescription == rhsError.localizedDescription
default: return false
}
}
}
// Copyright © 2019 Alexey Naumov. MIT License
import XCTest
@testable import AppName
class LoadableTests: XCTestCase {
func testEquality() {
let possibleValues: [Loadable<Int>] = [
.notRequested,
.isLoading(prevValue: nil),
.isLoading(prevValue: 9),
.loaded(5),
.loaded(6),
.failed(NSError(domain: "", code: 0, userInfo: nil))
]
possibleValues.enumerated().forEach { (index1, value1) in
possibleValues.enumerated().forEach { (index2, value2) in
if index1 == index2 {
XCTAssertEqual(value1, value2)
} else {
XCTAssertNotEqual(value1, value2)
}
}
}
}
func testHelpers() {
let notRequested = Loadable<Int>.notRequested
let loadingNil = Loadable<Int>.isLoading(prevValue: nil)
let loadingValue = Loadable<Int>.isLoading(prevValue: 9)
let loaded = Loadable<Int>.loaded(5)
let failedErrValue = Loadable<Int>.failed(NSError(domain: "", code: 0, userInfo: nil))
[notRequested, loadingNil].forEach {
XCTAssertNil($0.value)
}
[loadingValue, loaded].forEach {
XCTAssertNotNil($0.value)
}
[notRequested, loadingNil, loadingValue, loaded].forEach {
XCTAssertNil($0.error)
}
XCTAssertNotNil(failedErrValue.error)
XCTAssertTrue(loadingNil.isLoading)
XCTAssertTrue(loaded.isLoaded)
XCTAssertFalse(notRequested.isLoading)
XCTAssertFalse(loadingValue.isLoaded)
XCTAssertFalse(loaded.isFailed)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment