@@ -405,7 +405,7 @@ extension Deferred
405405
406406extension Deferred
407407{
408- /// Flatten a `Deferred<Deferred<Success>, Failure>` to a `Deferred<Success, Failure>`
408+ /// Flatten a `Deferred<Deferred<Success, Failure >, Failure>` to a `Deferred<Success, Failure>`
409409 ///
410410 /// In the right conditions, acts like a fast path for a flatMap with no transform.
411411 ///
@@ -462,7 +462,7 @@ extension Deferred
462462 }
463463 }
464464
465- /// Flatten a `Deferred<Deferred<Success>, Never>` to a `Deferred<Success, Failure>`
465+ /// Flatten a `Deferred<Deferred<Success, Failure >, Never>` to a `Deferred<Success, Failure>`
466466 ///
467467 /// In the right conditions, acts like a fast path for a flatMap with no transform.
468468 ///
@@ -516,7 +516,7 @@ extension Deferred
516516
517517}
518518
519- extension Deferred where Failure == Error
519+ extension Deferred
520520{
521521 /// Enqueue a transform to be computed asynchronously if and when `self` becomes resolved with an error.
522522 ///
@@ -526,7 +526,7 @@ extension Deferred where Failure == Error
526526 /// - parameter error: the Error to be transformed for the new `Deferred`
527527
528528 public func recover( queue: DispatchQueue ? = nil ,
529- transform: @escaping ( _ error: Error ) throws -> Deferred ) -> Deferred
529+ transform: @escaping ( _ error: Failure ) -> Deferred ) -> Deferred
530530 {
531531 return Deferred ( queue: queue ?? self . queue) {
532532 resolver in
@@ -535,24 +535,19 @@ extension Deferred where Failure == Error
535535 guard resolver. needsResolution else { return }
536536 switch result
537537 {
538- case let . success( value ) :
539- resolver. resolve ( value : value )
538+ case . success:
539+ resolver. resolve ( result )
540540
541541 case let . failure( error) :
542- do {
543- let transformed = try transform ( error)
544- if let transformed = transformed. peek ( )
545- {
546- resolver. resolve ( transformed)
547- }
548- else
549- {
550- transformed. notify ( queue: queue, handler: resolver. resolve)
551- resolver. retainSource ( transformed)
552- }
542+ let transformed = transform ( error)
543+ if let transformed = transformed. peek ( )
544+ {
545+ resolver. resolve ( transformed)
553546 }
554- catch {
555- resolver. resolve ( error: error)
547+ else
548+ {
549+ transformed. notify ( queue: queue, handler: resolver. resolve)
550+ resolver. retainSource ( transformed)
556551 }
557552 }
558553 }
@@ -568,7 +563,7 @@ extension Deferred where Failure == Error
568563 /// - parameter error: the Error to be transformed for the new `Deferred`
569564
570565 public func recover( qos: DispatchQoS ,
571- transform: @escaping ( _ error: Error ) throws -> Deferred ) -> Deferred
566+ transform: @escaping ( _ error: Failure ) -> Deferred ) -> Deferred
572567 {
573568 let queue = DispatchQueue ( label: " deferred-recover " , qos: qos)
574569 return recover ( queue: queue, transform: transform)
@@ -582,25 +577,86 @@ extension Deferred where Failure == Error
582577 /// - parameter qos: the QoS at which the computation (and notifications) should be performed; defaults to the current QoS class.
583578 /// - parameter task: the computation to be performed
584579
585- public static func RetryTask ( _ attempts: Int , qos: DispatchQoS = . current,
586- task: @escaping ( ) throws -> Success ) -> Deferred
580+ public static func Retrying ( _ attempts: Int , qos: DispatchQoS = . current,
581+ task: @escaping ( ) -> Deferred ) -> Deferred
587582 {
588- let queue = DispatchQueue ( label: " deferred " , qos: qos)
589- return Deferred . RetryTask ( attempts, queue: queue, task: task)
583+ let queue = DispatchQueue ( label: " retrying " , qos: qos)
584+ return Deferred . Retrying ( attempts, queue: queue, task: task)
590585 }
591586
592587 /// Initialize a `Deferred` with a computation task to be performed in the background
593588 ///
594589 /// If at first it does not succeed, it will try `attempts` times in total before being resolved with an `Error`.
595590 ///
596- /// - parameter attempts: a maximum number of times to attempt `task`
591+ /// - parameter attempts: a maximum number of times to attempt `task` (must be greater than zero)
597592 /// - parameter queue: the `DispatchQueue` on which the computation (and notifications) will be executed
598593 /// - parameter task: the computation to be performed
599594
600- public static func RetryTask ( _ attempts: Int , queue: DispatchQueue ,
601- task: @escaping ( ) throws -> Success ) -> Deferred
595+ public static func Retrying ( _ attempts: Int , queue: DispatchQueue ,
596+ task: @escaping ( ) -> Deferred ) -> Deferred
602597 {
603- return Deferred . Retrying ( attempts, queue: queue, task: { Deferred ( queue: queue, task: task) } )
598+ if attempts < 1
599+ {
600+ let message = " number of attempts must be greater than 0 in \( #function) "
601+ guard let error = Invalidation . invalid ( message) as? Failure else { fatalError ( message) }
602+ return Deferred ( error: error)
603+ }
604+
605+ return ( 1 ..< attempts) . reduce ( task ( ) ) {
606+ ( deferred, _) in
607+ deferred. recover ( transform: { _ in task ( ) } )
608+ }
609+ }
610+ }
611+
612+ extension Deferred where Failure == Error
613+ {
614+ /// Enqueue a transform to be computed asynchronously if and when `self` becomes resolved with an error.
615+ ///
616+ /// - parameter queue: the `DispatchQueue` to attach to the new `Deferred`; defaults to `self`'s queue.
617+ /// - parameter transform: the transform to be performed
618+ /// - returns: a `Deferred` reference representing the return value of the transform
619+ /// - parameter error: the Error to be transformed for the new `Deferred`
620+
621+ public func recover( queue: DispatchQueue ? = nil ,
622+ transform: @escaping ( _ error: Error ) throws -> Success ) -> Deferred
623+ {
624+ return Deferred ( queue: queue ?? self . queue) {
625+ resolver in
626+ self . notify ( queue: queue) {
627+ result in
628+ guard resolver. needsResolution else { return }
629+ switch result
630+ {
631+ case . success:
632+ resolver. resolve ( result)
633+
634+ case let . failure( error) :
635+ do {
636+ let value = try transform ( error)
637+ resolver. resolve ( value: value)
638+ }
639+ catch {
640+ resolver. resolve ( error: error)
641+ }
642+ }
643+ }
644+ resolver. retainSource ( self )
645+ }
646+ }
647+
648+ /// Enqueue a transform to be computed asynchronously if and when `self` becomes resolved with an error.
649+ ///
650+ /// - parameter qos: the QoS at which to execute the transform and the new `Deferred`'s notifications
651+ /// - parameter transform: the transform to be performed
652+ /// - returns: a `Deferred` reference representing the return value of the transform
653+ /// - parameter error: the Error to be transformed for the new `Deferred`
654+
655+ public func recover( qos: DispatchQoS ,
656+ transform: @escaping ( _ error: Error ) throws -> Success ) -> Deferred
657+ {
658+ let queue = DispatchQueue ( label: " deferred-recover " , qos: qos)
659+ return recover ( queue: queue, transform: transform)
604660 }
605661
606662 /// Initialize a `Deferred` with a computation task to be performed in the background
@@ -612,9 +668,9 @@ extension Deferred where Failure == Error
612668 /// - parameter task: the computation to be performed
613669
614670 public static func Retrying( _ attempts: Int , qos: DispatchQoS = . current,
615- task: @escaping ( ) throws -> Deferred ) -> Deferred
671+ task: @escaping ( ) throws -> Success ) -> Deferred
616672 {
617- let queue = DispatchQueue ( label: " retrying " , qos: qos)
673+ let queue = DispatchQueue ( label: " deferred " , qos: qos)
618674 return Deferred . Retrying ( attempts, queue: queue, task: task)
619675 }
620676
@@ -627,19 +683,15 @@ extension Deferred where Failure == Error
627683 /// - parameter task: the computation to be performed
628684
629685 public static func Retrying( _ attempts: Int , queue: DispatchQueue ,
630- task: @escaping ( ) throws -> Deferred ) -> Deferred
686+ task: @escaping ( ) throws -> Success ) -> Deferred
631687 {
632- let error = Invalidation . invalid ( " task was not allowed a single attempt in \( #function) " )
633- let deferred = Deferred ( queue: queue, error: error)
634-
635- if attempts < 1 { return deferred }
636-
637- return Deferred . Retrying ( attempts, deferred, task: task)
638- }
688+ if attempts < 1
689+ {
690+ let message = " number of attempts must be greater than 0 in \( #function) "
691+ return Deferred ( queue: queue, error: Invalidation . invalid ( message) )
692+ }
639693
640- private static func Retrying( _ attempts: Int , _ deferred: Deferred , task: @escaping ( ) throws -> Deferred ) -> Deferred
641- {
642- return ( 0 ..< attempts) . reduce ( deferred) {
694+ return ( 1 ..< attempts) . reduce ( Deferred ( queue: queue, task: task) ) {
643695 ( deferred, _) in
644696 deferred. recover ( transform: { _ in try task ( ) } )
645697 }
0 commit comments