-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEnumerated.swift
42 lines (36 loc) · 1.23 KB
/
Enumerated.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import Combine
import Foundation
import Synchronized
public extension Publisher {
func enumerated(startIndex: Int = 0) -> Publishers.Enumerated<Self> {
Publishers.Enumerated(upstream: self, startIndex: startIndex)
}
}
public extension Publishers {
struct Enumerated<Upstream: Publisher>: Publisher {
public typealias Output = (Int, Upstream.Output)
public typealias Failure = Upstream.Failure
private let upstream: Upstream
private let startIndex: Int
public init(upstream: Upstream, startIndex: Int = 0) {
self.upstream = upstream
self.startIndex = startIndex
}
public func receive<S: Subscriber>(
subscriber: S
) where Output == S.Input, Failure == S.Failure {
let lock = Lock()
var index = startIndex
upstream
.map { (value: Upstream.Output) -> (Int, Upstream.Output) in
let i: Int = lock.locked {
let i = index
index = index &+ 1
return i
}
return (i, value)
}
.receive(subscriber: subscriber)
}
}
}