// // fromAsync.swift // RxSwiftExt // // Created by Vincent on 12/08/2017. // Copyright © 2017 RxSwift Community. All rights reserved. // import Foundation import RxSwift extension Observable { /** Transforms an async function that returns data through a completionHandler in a function that returns data through an Observable - The returned function will thake the same arguments than asyncRequest, minus the last one */ public static func fromAsync(_ asyncRequest: @escaping (@escaping (Element) -> Void) -> Void) -> Observable { return Observable.create({ (o) -> Disposable in asyncRequest({ (result) in o.onNext(result) o.onCompleted() }) return Disposables.create() }) } public static func fromAsync(_ asyncRequest: @escaping (A, @escaping (Element) -> Void) -> Void) -> (A) -> Observable { return { (a: A) in Observable.fromAsync(curry(asyncRequest)(a)) } } public static func fromAsync(_ asyncRequest: @escaping (A, B, @escaping (Element) -> Void) -> Void) -> (A, B) -> Observable { return { (a: A, b: B) in Observable.fromAsync(curry(asyncRequest)(a)(b)) } } public static func fromAsync(_ asyncRequest: @escaping (A, B, C, @escaping (Element) -> Void) -> Void) -> (A, B, C) -> Observable { return { (a: A, b: B, c: C) in Observable.fromAsync(curry(asyncRequest)(a)(b)(c)) } } public static func fromAsync(_ asyncRequest: @escaping (A, B, C, D, @escaping (Element) -> Void) -> Void) -> (A, B, C, D) -> Observable { return { (a: A, b: B, c: C, d: D) in Observable.fromAsync(curry(asyncRequest)(a)(b)(c)(d)) } } public static func fromAsync(_ asyncRequest: @escaping (A, B, C, D, E, @escaping (Element) -> Void) -> Void) -> (A, B, C, D, E) -> Observable { return { (a: A, b: B, c: C, d: D, e: E) in Observable.fromAsync(curry(asyncRequest)(a)(b)(c)(d)(e)) } } public static func fromAsync(_ asyncRequest: @escaping (A, B, C, D, E, F, @escaping (Element) -> Void) -> Void) -> (A, B, C, D, E, F) -> Observable { return { (a: A, b: B, c: C, d: D, e: E, f: F) in Observable.fromAsync(curry(asyncRequest)(a)(b)(c)(d)(e)(f)) } } public static func fromAsync(_ asyncRequest: @escaping (A, B, C, D, E, F, G, @escaping (Element) -> Void) -> Void) -> (A, B, C, D, E, F, G) -> Observable { return { (a: A, b: B, c: C, d: D, e: E, f: F, g: G) in Observable.fromAsync(curry(asyncRequest)(a)(b)(c)(d)(e)(f)(g)) } } public static func fromAsync(_ asyncRequest: @escaping (A, B, C, D, E, F, G, H, @escaping (Element) -> Void) -> Void) -> (A, B, C, D, E, F, G, H) -> Observable { return { (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H) in Observable.fromAsync(curry(asyncRequest)(a)(b)(c)(d)(e)(f)(g)(h)) } } public static func fromAsync(_ asyncRequest: @escaping (A, B, C, D, E, F, G, H, I, @escaping (Element) -> Void) -> Void) -> (A, B, C, D, E, F, G, H, I) -> Observable { return { (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I) in Observable.fromAsync(curry(asyncRequest)(a)(b)(c)(d)(e)(f)(g)(h)(i)) } } public static func fromAsync(_ asyncRequest: @escaping (A, B, C, D, E, F, G, H, I, J, @escaping (Element) -> Void) -> Void) -> (A, B, C, D, E, F, G, H, I, J) -> Observable { return { (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J) in Observable.fromAsync(curry(asyncRequest)(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)) } } } public enum FromAsyncError: Error { /// Both result & error can't be nil case inconsistentCompletionResult } public extension PrimitiveSequenceType where Trait == SingleTrait { /** Transforms an async function that returns data or error through a completionHandler in a function that returns data through a Single - The returned function will thake the same arguments than asyncRequest, minus the last one */ static func fromAsync(_ asyncRequest: @escaping (@escaping (Element?, Er?) -> Void) -> Void) -> Single { return .create { single in asyncRequest { result, error in switch (result, error) { case let (.some(result), nil): single(.success(result)) case let (nil, .some(error)): single(.error(error)) default: single(.error(FromAsyncError.inconsistentCompletionResult)) } } return Disposables.create() } } static func fromAsync(_ asyncRequest: @escaping (A, @escaping (Element?, Er?) -> Void) -> Void) -> (A) -> Single { return { (a: A) in Single.fromAsync(curry(asyncRequest)(a)) } } static func fromAsync(_ asyncRequest: @escaping (A, B, @escaping (Element?, Er?) -> Void) -> Void) -> (A, B) -> Single { return { (a: A, b: B) in Single.fromAsync(curry(asyncRequest)(a)(b)) } } static func fromAsync(_ asyncRequest: @escaping (A, B, C, @escaping (Element?, Er?) -> Void) -> Void) -> (A, B, C) -> Single { return { (a: A, b: B, c: C) in Single.fromAsync(curry(asyncRequest)(a)(b)(c)) } } static func fromAsync(_ asyncRequest: @escaping (A, B, C, D, @escaping (Element?, Er?) -> Void) -> Void) -> (A, B, C, D) -> Single { return { (a: A, b: B, c: C, d: D) in Single.fromAsync(curry(asyncRequest)(a)(b)(c)(d)) } } static func fromAsync(_ asyncRequest: @escaping (A, B, C, D, E, @escaping (Element?, Er?) -> Void) -> Void) -> (A, B, C, D, E) -> Single { return { (a: A, b: B, c: C, d: D, e: E) in Single.fromAsync(curry(asyncRequest)(a)(b)(c)(d)(e)) } } static func fromAsync(_ asyncRequest: @escaping (A, B, C, D, E, F, @escaping (Element?, Er?) -> Void) -> Void) -> (A, B, C, D, E, F) -> Single { return { (a: A, b: B, c: C, d: D, e: E, f: F) in Single.fromAsync(curry(asyncRequest)(a)(b)(c)(d)(e)(f)) } } static func fromAsync(_ asyncRequest: @escaping (A, B, C, D, E, F, G, @escaping (Element?, Er?) -> Void) -> Void) -> (A, B, C, D, E, F, G) -> Single { return { (a: A, b: B, c: C, d: D, e: E, f: F, g: G) in Single.fromAsync(curry(asyncRequest)(a)(b)(c)(d)(e)(f)(g)) } } static func fromAsync(_ asyncRequest: @escaping (A, B, C, D, E, F, G, H, @escaping (Element?, Er?) -> Void) -> Void) -> (A, B, C, D, E, F, G, H) -> Single { return { (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H) in Single.fromAsync(curry(asyncRequest)(a)(b)(c)(d)(e)(f)(g)(h)) } } static func fromAsync(_ asyncRequest: @escaping (A, B, C, D, E, F, G, H, I, @escaping (Element?, Er?) -> Void) -> Void) -> (A, B, C, D, E, F, G, H, I) -> Single { return { (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I) in Single.fromAsync(curry(asyncRequest)(a)(b)(c)(d)(e)(f)(g)(h)(i)) } } static func fromAsync(_ asyncRequest: @escaping (A, B, C, D, E, F, G, H, I, J, @escaping (Element?, Er?) -> Void) -> Void) -> (A, B, C, D, E, F, G, H, I, J) -> Single { return { (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J) in Single.fromAsync(curry(asyncRequest)(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)) } } }