Skip to content

Commit

Permalink
chore(merge): merge #39 into main
Browse files Browse the repository at this point in the history
  • Loading branch information
sbertix authored May 26, 2021
2 parents 564ec8f + 887ba6f commit d4f0198
Show file tree
Hide file tree
Showing 5 changed files with 256 additions and 141 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,12 @@ public extension LockProviderType {
Self.generate(self, from: key)
}
}

public extension LockProviderType where Input == Void {
/// Unlock.
///
/// - returns: Some `Content`.
func unlock() -> Output {
Self.generate(self, from: ())
}
}
139 changes: 118 additions & 21 deletions Sources/ComposableRequest/Publishers/Pager/Pager+Iteration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,10 @@ public extension Publisher {
/// - returns: A valid `Pager.Iteration`.
func iterate<O>(stoppingAt exception: @escaping (O) -> Bool,
with offset: @escaping ([Output]) -> Instruction<O>) -> Pager<O, Self>.Iteration {
iterate {
switch offset($0) {
case .stop:
return .stop
case .load(let next):
return exception(next) ? .stop : .load(next)
}
iterate { value -> Instruction<O> in
let instruction = offset(value)
guard case .load(let next) = instruction else { return instruction }
return exception(next) ? .stop : .load(next)
}
}

Expand Down Expand Up @@ -78,13 +75,10 @@ public extension Publisher {
/// - offet: A valid offset generator.
/// - returns: A valid `Pager.Iteration`.
func iterateFirst<O>(stoppingAt exception: @escaping (O) -> Bool, with offset: @escaping (Output?) -> Instruction<O>) -> Pager<O, Publishers.Output<Self>>.Iteration {
iterateFirst {
switch offset($0) {
case .stop:
return .stop
case .load(let next):
return exception(next) ? .stop : .load(next)
}
iterateFirst { value -> Instruction<O> in
let instruction = offset(value)
guard case .load(let next) = instruction else { return instruction }
return exception(next) ? .stop : .load(next)
}
}

Expand Down Expand Up @@ -113,13 +107,10 @@ public extension Publisher {
/// - offet: A valid offset generator.
/// - returns: A valid `Pager.Iteration`.
func iterateLast<O>(stoppingAt exception: @escaping (O) -> Bool, with offset: @escaping (Output?) -> Instruction<O>) -> Pager<O, Publishers.Last<Self>>.Iteration {
iterateLast {
switch offset($0) {
case .stop:
return .stop
case .load(let next):
return exception(next) ? .stop : .load(next)
}
iterateLast { value -> Instruction<O> in
let instruction = offset(value)
guard case .load(let next) = instruction else { return instruction }
return exception(next) ? .stop : .load(next)
}
}

Expand All @@ -140,6 +131,112 @@ public extension Publisher {
func iterate(_ `continue`: @escaping ([Output]) -> Bool = { _ in true }) -> Pager<Void, Self>.Iteration {
.init(stream: self) { `continue`($0) ? .load(()) : .stop }
}

// MARK: Optional

/// Create the iteration.
///
/// - parameter offset: A valid offset generator.
/// - returns: A valid `Pager.Iteration`.
func iterate<W>(with offset: @escaping ([Output]) -> Instruction<W>) -> Pager<W?, Self>.Iteration {
self.iterate { value -> Instruction<W?> in
switch offset(value) {
case .stop:
return .stop
case .load(let offset):
return .load(offset)
}
}
}

/// Create the iteration, making sure we don't get stuck inside an infinite loop.
///
/// - parameters:
/// - exception: A valid `Offset` handler. Return `true` to stop the stream.
/// - offet: A valid offset generator.
/// - returns: A valid `Pager.Iteration`.
func iterate<W>(stoppingAt exception: @escaping (W?) -> Bool,
with offset: @escaping ([Output]) -> Instruction<W>) -> Pager<W?, Self>.Iteration {
iterate { value -> Instruction<W> in
let instruction = offset(value)
guard case .load(let next) = instruction else { return instruction }
return exception(next) ? .stop : .load(next)
}
}

/// Create the iteration, making sure we don't get stuck inside an infinite loop.
///
/// - parameters:
/// - exception: A valid `Offset`.
/// - offet: A valid offset generator.
/// - returns: A valid `Pager.Iteration`.
func iterate<W>(stoppingAt exception: W?, with offset: @escaping ([Output]) -> Instruction<W>) -> Pager<W?, Self>.Iteration where W: Equatable {
iterate(stoppingAt: { $0 == exception }, with: offset)
}

/// Create the iteration, after only one output.
///
/// - parameter offset: A valid offset generator.
/// - returns: A valid `Pager.Iteration`.
func iterateFirst<W>(with offset: @escaping (Output?) -> Instruction<W>) -> Pager<W?, Publishers.Output<Self>>.Iteration {
prefix(1).iterate { offset($0.first) }
}

/// Create the iteration, after only one output, making sure we don't get stuck inside an infinite loop.
///
/// - parameters:
/// - exception: A valid `Offset` handler. Return `true` to stop the stream.
/// - offet: A valid offset generator.
/// - returns: A valid `Pager.Iteration`.
func iterateFirst<W>(stoppingAt exception: @escaping (W?) -> Bool, with offset: @escaping (Output?) -> Instruction<W>) -> Pager<W?, Publishers.Output<Self>>.Iteration {
iterateFirst { value -> Instruction<W> in
let instruction = offset(value)
guard case .load(let next) = instruction else { return instruction }
return exception(next) ? .stop : .load(next)
}
}

/// Create the iteration, after only one output, making sure we don't get stuck inside an infinite loop.
///
/// - parameters:
/// - exception: A valid `Offset`.
/// - offet: A valid offset generator.
/// - returns: A valid `Pager.Iteration`.
func iterateFirst<W>(stoppingAt exception: W?, with offset: @escaping (Output?) -> Instruction<W>) -> Pager<W?, Publishers.Output<Self>>.Iteration where W: Equatable {
iterateFirst(stoppingAt: { $0 == exception }, with: offset)
}

/// Create the iteration, on the last output alone.
///
/// - parameter offset: A valid offset generator.
/// - returns: A valid `Pager.Iteration`.
func iterateLast<W>(with offset: @escaping (Output?) -> Instruction<W>) -> Pager<W?, Publishers.Last<Self>>.Iteration {
last().iterate { offset($0.first) }
}

/// Create the iteration, on the last output alone., making sure we don't get stuck inside an infinite loop.
///
/// - parameters:
/// - exception: A valid `Offset` handler. Return `true` to stop the stream.
/// - offet: A valid offset generator.
/// - returns: A valid `Pager.Iteration`.
func iterateLast<W>(stoppingAt exception: @escaping (W?) -> Bool, with offset: @escaping (Output?) -> Instruction<W>) -> Pager<W?, Publishers.Last<Self>>.Iteration {
iterateLast { value -> Instruction<W> in
let instruction = offset(value)
guard case .load(let next) = instruction else { return instruction }
return exception(next) ? .stop : .load(next)
}
}

/// Create the iteration, on the last output alone., making sure we don't get stuck inside an infinite loop.
///
/// - parameters:
/// - exception: A valid `Offset`.
/// - offet: A valid offset generator.
/// - returns: A valid `Pager.Iteration`.
func iterateLast<W>(stoppingAt exception: W?, with offset: @escaping (Output?) -> Instruction<W>) -> Pager<W?, Publishers.Last<Self>>.Iteration where W: Equatable {
iterateLast(stoppingAt: { $0 == exception }, with: offset)
}
}

public extension Publisher where Failure == Never {
Expand Down
31 changes: 27 additions & 4 deletions Sources/ComposableRequest/Publishers/Pager/Pager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ public extension Publishers {
self.generator = generator
}

/// Init.
///
/// - parameters:
/// - count: A valid `Int`. Defaults to `.max`.
/// - offset: A valid `Offset`.
/// - delay: A valid `Delay`.
/// - generator: A valid generator.
public init(_ count: Int = .max,
offset: Offset,
delay: Delay,
generator: @escaping (_ offset: Offset) -> Iteration) {
self.init(count, offset: offset, delay: { _ in delay }, generator: generator)
}

/// Init.
///
/// - parameters:
Expand Down Expand Up @@ -77,10 +91,19 @@ public extension Publishers {
case .stop:
return current.eraseToAnyPublisher()
case .load(let next):
return current
.append(Deferred { Pager(count - 1, offset: next, delay: delay, generator: generator) }
.delay(for: count - 1 > 0 ? delay(next) : .zero, scheduler: RunLoop.main))
.eraseToAnyPublisher()
switch count - 1 > 0 ? delay(next) : .zero {
case ...0:
return current
.append(Deferred { Pager(count - 1, offset: next, delay: delay, generator: generator) })
.eraseToAnyPublisher()
case let delay:
return current
.append(
Deferred { Pager(count - 1, offset: next, delay: self.delay, generator: generator) }
.delay(for: delay, scheduler: RunLoop.main)
)
.eraseToAnyPublisher()
}
}
}
.subscribe(subscriber)
Expand Down
Loading

0 comments on commit d4f0198

Please sign in to comment.