import Foundation import RxSwift #if !COCOAPODS import Moya #endif #if canImport(UIKit) import UIKit.UIImage #elseif canImport(AppKit) import AppKit.NSImage #endif /// Extension for processing raw NSData generated by network access. extension ObservableType where Element == Response { /// Filters out responses that don't fall within the given range, generating errors when others are encountered. public func filter(statusCodes: R) -> Observable where R.Bound == Int { return flatMap { Observable.just(try $0.filter(statusCodes: statusCodes)) } } /// Filters out responses that has the specified `statusCode`. public func filter(statusCode: Int) -> Observable { return flatMap { Observable.just(try $0.filter(statusCode: statusCode)) } } /// Filters out responses where `statusCode` falls within the range 200 - 299. public func filterSuccessfulStatusCodes() -> Observable { return flatMap { Observable.just(try $0.filterSuccessfulStatusCodes()) } } /// Filters out responses where `statusCode` falls within the range 200 - 399 public func filterSuccessfulStatusAndRedirectCodes() -> Observable { return flatMap { Observable.just(try $0.filterSuccessfulStatusAndRedirectCodes()) } } /// Maps data received from the signal into an Image. If the conversion fails, the signal errors. public func mapImage() -> Observable { return flatMap { Observable.just(try $0.mapImage()) } } /// Maps data received from the signal into a JSON object. If the conversion fails, the signal errors. public func mapJSON(failsOnEmptyData: Bool = true) -> Observable { return flatMap { Observable.just(try $0.mapJSON(failsOnEmptyData: failsOnEmptyData)) } } /// Maps received data at key path into a String. If the conversion fails, the signal errors. public func mapString(atKeyPath keyPath: String? = nil) -> Observable { return flatMap { Observable.just(try $0.mapString(atKeyPath: keyPath)) } } /// Maps received data at key path into a Decodable object. If the conversion fails, the signal errors. public func map(_ type: D.Type, atKeyPath keyPath: String? = nil, using decoder: JSONDecoder = JSONDecoder(), failsOnEmptyData: Bool = true) -> Observable { return flatMap { Observable.just(try $0.map(type, atKeyPath: keyPath, using: decoder, failsOnEmptyData: failsOnEmptyData)) } } } extension ObservableType where Element == ProgressResponse { /** Filter completed progress response and maps to actual response - returns: response associated with ProgressResponse object */ public func filterCompleted() -> Observable { return self .filter { $0.completed } .flatMap { progress -> Observable in // Just a formatlity to satisfy the compiler (completed progresses have responses). switch progress.response { case .some(let response): return .just(response) case .none: return .empty() } } } /** Filter progress events of current ProgressResponse - returns: observable of progress events */ public func filterProgress() -> Observable { return self.filter { !$0.completed }.map { $0.progress } } }