Skip to content

Commit d4f0198

Browse files
authored
chore(merge): merge #39 into main
2 parents 564ec8f + 887ba6f commit d4f0198

File tree

5 files changed

+256
-141
lines changed

5 files changed

+256
-141
lines changed

Sources/ComposableRequest/Providers/Lock/LockProviderType.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,12 @@ public extension LockProviderType {
1919
Self.generate(self, from: key)
2020
}
2121
}
22+
23+
public extension LockProviderType where Input == Void {
24+
/// Unlock.
25+
///
26+
/// - returns: Some `Content`.
27+
func unlock() -> Output {
28+
Self.generate(self, from: ())
29+
}
30+
}

Sources/ComposableRequest/Publishers/Pager/Pager+Iteration.swift

Lines changed: 118 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,10 @@ public extension Publisher {
4343
/// - returns: A valid `Pager.Iteration`.
4444
func iterate<O>(stoppingAt exception: @escaping (O) -> Bool,
4545
with offset: @escaping ([Output]) -> Instruction<O>) -> Pager<O, Self>.Iteration {
46-
iterate {
47-
switch offset($0) {
48-
case .stop:
49-
return .stop
50-
case .load(let next):
51-
return exception(next) ? .stop : .load(next)
52-
}
46+
iterate { value -> Instruction<O> in
47+
let instruction = offset(value)
48+
guard case .load(let next) = instruction else { return instruction }
49+
return exception(next) ? .stop : .load(next)
5350
}
5451
}
5552

@@ -78,13 +75,10 @@ public extension Publisher {
7875
/// - offet: A valid offset generator.
7976
/// - returns: A valid `Pager.Iteration`.
8077
func iterateFirst<O>(stoppingAt exception: @escaping (O) -> Bool, with offset: @escaping (Output?) -> Instruction<O>) -> Pager<O, Publishers.Output<Self>>.Iteration {
81-
iterateFirst {
82-
switch offset($0) {
83-
case .stop:
84-
return .stop
85-
case .load(let next):
86-
return exception(next) ? .stop : .load(next)
87-
}
78+
iterateFirst { value -> Instruction<O> in
79+
let instruction = offset(value)
80+
guard case .load(let next) = instruction else { return instruction }
81+
return exception(next) ? .stop : .load(next)
8882
}
8983
}
9084

@@ -113,13 +107,10 @@ public extension Publisher {
113107
/// - offet: A valid offset generator.
114108
/// - returns: A valid `Pager.Iteration`.
115109
func iterateLast<O>(stoppingAt exception: @escaping (O) -> Bool, with offset: @escaping (Output?) -> Instruction<O>) -> Pager<O, Publishers.Last<Self>>.Iteration {
116-
iterateLast {
117-
switch offset($0) {
118-
case .stop:
119-
return .stop
120-
case .load(let next):
121-
return exception(next) ? .stop : .load(next)
122-
}
110+
iterateLast { value -> Instruction<O> in
111+
let instruction = offset(value)
112+
guard case .load(let next) = instruction else { return instruction }
113+
return exception(next) ? .stop : .load(next)
123114
}
124115
}
125116

@@ -140,6 +131,112 @@ public extension Publisher {
140131
func iterate(_ `continue`: @escaping ([Output]) -> Bool = { _ in true }) -> Pager<Void, Self>.Iteration {
141132
.init(stream: self) { `continue`($0) ? .load(()) : .stop }
142133
}
134+
135+
// MARK: Optional
136+
137+
/// Create the iteration.
138+
///
139+
/// - parameter offset: A valid offset generator.
140+
/// - returns: A valid `Pager.Iteration`.
141+
func iterate<W>(with offset: @escaping ([Output]) -> Instruction<W>) -> Pager<W?, Self>.Iteration {
142+
self.iterate { value -> Instruction<W?> in
143+
switch offset(value) {
144+
case .stop:
145+
return .stop
146+
case .load(let offset):
147+
return .load(offset)
148+
}
149+
}
150+
}
151+
152+
/// Create the iteration, making sure we don't get stuck inside an infinite loop.
153+
///
154+
/// - parameters:
155+
/// - exception: A valid `Offset` handler. Return `true` to stop the stream.
156+
/// - offet: A valid offset generator.
157+
/// - returns: A valid `Pager.Iteration`.
158+
func iterate<W>(stoppingAt exception: @escaping (W?) -> Bool,
159+
with offset: @escaping ([Output]) -> Instruction<W>) -> Pager<W?, Self>.Iteration {
160+
iterate { value -> Instruction<W> in
161+
let instruction = offset(value)
162+
guard case .load(let next) = instruction else { return instruction }
163+
return exception(next) ? .stop : .load(next)
164+
}
165+
}
166+
167+
/// Create the iteration, making sure we don't get stuck inside an infinite loop.
168+
///
169+
/// - parameters:
170+
/// - exception: A valid `Offset`.
171+
/// - offet: A valid offset generator.
172+
/// - returns: A valid `Pager.Iteration`.
173+
func iterate<W>(stoppingAt exception: W?, with offset: @escaping ([Output]) -> Instruction<W>) -> Pager<W?, Self>.Iteration where W: Equatable {
174+
iterate(stoppingAt: { $0 == exception }, with: offset)
175+
}
176+
177+
/// Create the iteration, after only one output.
178+
///
179+
/// - parameter offset: A valid offset generator.
180+
/// - returns: A valid `Pager.Iteration`.
181+
func iterateFirst<W>(with offset: @escaping (Output?) -> Instruction<W>) -> Pager<W?, Publishers.Output<Self>>.Iteration {
182+
prefix(1).iterate { offset($0.first) }
183+
}
184+
185+
/// Create the iteration, after only one output, making sure we don't get stuck inside an infinite loop.
186+
///
187+
/// - parameters:
188+
/// - exception: A valid `Offset` handler. Return `true` to stop the stream.
189+
/// - offet: A valid offset generator.
190+
/// - returns: A valid `Pager.Iteration`.
191+
func iterateFirst<W>(stoppingAt exception: @escaping (W?) -> Bool, with offset: @escaping (Output?) -> Instruction<W>) -> Pager<W?, Publishers.Output<Self>>.Iteration {
192+
iterateFirst { value -> Instruction<W> in
193+
let instruction = offset(value)
194+
guard case .load(let next) = instruction else { return instruction }
195+
return exception(next) ? .stop : .load(next)
196+
}
197+
}
198+
199+
/// Create the iteration, after only one output, making sure we don't get stuck inside an infinite loop.
200+
///
201+
/// - parameters:
202+
/// - exception: A valid `Offset`.
203+
/// - offet: A valid offset generator.
204+
/// - returns: A valid `Pager.Iteration`.
205+
func iterateFirst<W>(stoppingAt exception: W?, with offset: @escaping (Output?) -> Instruction<W>) -> Pager<W?, Publishers.Output<Self>>.Iteration where W: Equatable {
206+
iterateFirst(stoppingAt: { $0 == exception }, with: offset)
207+
}
208+
209+
/// Create the iteration, on the last output alone.
210+
///
211+
/// - parameter offset: A valid offset generator.
212+
/// - returns: A valid `Pager.Iteration`.
213+
func iterateLast<W>(with offset: @escaping (Output?) -> Instruction<W>) -> Pager<W?, Publishers.Last<Self>>.Iteration {
214+
last().iterate { offset($0.first) }
215+
}
216+
217+
/// Create the iteration, on the last output alone., making sure we don't get stuck inside an infinite loop.
218+
///
219+
/// - parameters:
220+
/// - exception: A valid `Offset` handler. Return `true` to stop the stream.
221+
/// - offet: A valid offset generator.
222+
/// - returns: A valid `Pager.Iteration`.
223+
func iterateLast<W>(stoppingAt exception: @escaping (W?) -> Bool, with offset: @escaping (Output?) -> Instruction<W>) -> Pager<W?, Publishers.Last<Self>>.Iteration {
224+
iterateLast { value -> Instruction<W> in
225+
let instruction = offset(value)
226+
guard case .load(let next) = instruction else { return instruction }
227+
return exception(next) ? .stop : .load(next)
228+
}
229+
}
230+
231+
/// Create the iteration, on the last output alone., making sure we don't get stuck inside an infinite loop.
232+
///
233+
/// - parameters:
234+
/// - exception: A valid `Offset`.
235+
/// - offet: A valid offset generator.
236+
/// - returns: A valid `Pager.Iteration`.
237+
func iterateLast<W>(stoppingAt exception: W?, with offset: @escaping (Output?) -> Instruction<W>) -> Pager<W?, Publishers.Last<Self>>.Iteration where W: Equatable {
238+
iterateLast(stoppingAt: { $0 == exception }, with: offset)
239+
}
143240
}
144241

145242
public extension Publisher where Failure == Never {

Sources/ComposableRequest/Publishers/Pager/Pager.swift

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,20 @@ public extension Publishers {
4242
self.generator = generator
4343
}
4444

45+
/// Init.
46+
///
47+
/// - parameters:
48+
/// - count: A valid `Int`. Defaults to `.max`.
49+
/// - offset: A valid `Offset`.
50+
/// - delay: A valid `Delay`.
51+
/// - generator: A valid generator.
52+
public init(_ count: Int = .max,
53+
offset: Offset,
54+
delay: Delay,
55+
generator: @escaping (_ offset: Offset) -> Iteration) {
56+
self.init(count, offset: offset, delay: { _ in delay }, generator: generator)
57+
}
58+
4559
/// Init.
4660
///
4761
/// - parameters:
@@ -77,10 +91,19 @@ public extension Publishers {
7791
case .stop:
7892
return current.eraseToAnyPublisher()
7993
case .load(let next):
80-
return current
81-
.append(Deferred { Pager(count - 1, offset: next, delay: delay, generator: generator) }
82-
.delay(for: count - 1 > 0 ? delay(next) : .zero, scheduler: RunLoop.main))
83-
.eraseToAnyPublisher()
94+
switch count - 1 > 0 ? delay(next) : .zero {
95+
case ...0:
96+
return current
97+
.append(Deferred { Pager(count - 1, offset: next, delay: delay, generator: generator) })
98+
.eraseToAnyPublisher()
99+
case let delay:
100+
return current
101+
.append(
102+
Deferred { Pager(count - 1, offset: next, delay: self.delay, generator: generator) }
103+
.delay(for: delay, scheduler: RunLoop.main)
104+
)
105+
.eraseToAnyPublisher()
106+
}
84107
}
85108
}
86109
.subscribe(subscriber)

0 commit comments

Comments
 (0)