mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
131 lines
3.9 KiB
Swift
131 lines
3.9 KiB
Swift
import Foundation
|
|
|
|
public func map<T, E, R>(_ f: @escaping(T) -> R) -> (Signal<T, E>) -> Signal<R, E> {
|
|
return { signal in
|
|
return Signal<R, E> { subscriber in
|
|
return signal.start(next: { next in
|
|
subscriber.putNext(f(next))
|
|
}, error: { error in
|
|
subscriber.putError(error)
|
|
}, completed: {
|
|
subscriber.putCompletion()
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
public func filter<T, E>(_ f: @escaping(T) -> Bool) -> (Signal<T, E>) -> Signal<T, E> {
|
|
return { signal in
|
|
return Signal<T, E> { subscriber in
|
|
return signal.start(next: { next in
|
|
if f(next) {
|
|
subscriber.putNext(next)
|
|
}
|
|
}, error: { error in
|
|
subscriber.putError(error)
|
|
}, completed: {
|
|
subscriber.putCompletion()
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
public func flatMap<T, E, R>(_ f: @escaping (T) -> R) -> (Signal<T?, E>) -> Signal<R?, E> {
|
|
return { signal in
|
|
return Signal<R?, E> { subscriber in
|
|
return signal.start(next: { next in
|
|
if let next = next {
|
|
subscriber.putNext(f(next))
|
|
} else {
|
|
subscriber.putNext(nil)
|
|
}
|
|
}, error: { error in
|
|
subscriber.putError(error)
|
|
}, completed: {
|
|
subscriber.putCompletion()
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
public func mapError<T, E, R>(_ f: @escaping(E) -> R) -> (Signal<T, E>) -> Signal<T, R> {
|
|
return { signal in
|
|
return Signal<T, R> { subscriber in
|
|
return signal.start(next: { next in
|
|
subscriber.putNext(next)
|
|
}, error: { error in
|
|
subscriber.putError(f(error))
|
|
}, completed: {
|
|
subscriber.putCompletion()
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
public func castError<T, E>(_ type: E.Type) -> (Signal<T, NoError>) -> Signal<T, E> {
|
|
return { signal in
|
|
return Signal<T, E> { subscriber in
|
|
return signal.start(next: { next in
|
|
subscriber.putNext(next)
|
|
}, error: { _ in
|
|
}, completed: {
|
|
subscriber.putCompletion()
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
private class DistinctUntilChangedContext<T> {
|
|
var value: T?
|
|
}
|
|
|
|
public func distinctUntilChanged<T: Equatable, E>(_ signal: Signal<T, E>) -> Signal<T, E> {
|
|
return Signal { subscriber in
|
|
let context = Atomic(value: DistinctUntilChangedContext<T>())
|
|
|
|
return signal.start(next: { next in
|
|
let pass = context.with { context -> Bool in
|
|
if let value = context.value, value == next {
|
|
return false
|
|
} else {
|
|
context.value = next
|
|
return true
|
|
}
|
|
}
|
|
if pass {
|
|
subscriber.putNext(next)
|
|
}
|
|
}, error: { error in
|
|
subscriber.putError(error)
|
|
}, completed: {
|
|
subscriber.putCompletion()
|
|
})
|
|
}
|
|
}
|
|
|
|
public func distinctUntilChanged<T, E>(isEqual: @escaping (T, T) -> Bool) -> (_ signal: Signal<T, E>) -> Signal<T, E> {
|
|
return { signal in
|
|
return Signal { subscriber in
|
|
let context = Atomic(value: DistinctUntilChangedContext<T>())
|
|
|
|
return signal.start(next: { next in
|
|
let pass = context.with { context -> Bool in
|
|
if let value = context.value, isEqual(value, next) {
|
|
return false
|
|
} else {
|
|
context.value = next
|
|
return true
|
|
}
|
|
}
|
|
if pass {
|
|
subscriber.putNext(next)
|
|
}
|
|
}, error: { error in
|
|
subscriber.putError(error)
|
|
}, completed: {
|
|
subscriber.putCompletion()
|
|
})
|
|
}
|
|
}
|
|
}
|