Skip to content

Instantly share code, notes, and snippets.

@danielt1263
Last active December 6, 2021 21:36
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danielt1263/2b624d7c925d8b7910ef2f1e5afe177b to your computer and use it in GitHub Desktop.
Save danielt1263/2b624d7c925d8b7910ef2f1e5afe177b to your computer and use it in GitHub Desktop.
//
// StallUnless.swift
//
// Created by Daniel Tartaglia on Oct 1, 2018.
// Copyright © 2021 Daniel Tartaglia. MIT License.
//
import RxSwift
extension ObservableType {
/**
Emits values immediately if the boundary sequence last emitted true,
otherwise collects elements from the source sequence until the boundary
sequence emits true then emits the collected elements.
- parameter boundary: Triggering event sequence.
- parameter initial: The initial value of the boundary
- returns: An Observable sequence.
*/
func stall<O>(unless boundary: O, initial: Bool) -> Observable<Element> where O: ObservableType, O.Element == Bool {
let shared = self.share()
return Observable.merge(
shared.map(Action.value),
boundary
.startWith(initial)
.distinctUntilChanged()
.materialize()
.map(Action.trigger)
.take(until: shared.takeLast(1))
)
.scan((buffer: [Element](), trigger: initial, out: [Element]()), accumulator: { current, new in
switch new {
case .value(let value):
return current.trigger ? (buffer: [], trigger: current.trigger, out: [value]) : (buffer: current.buffer + [value], trigger: current.trigger, out: [])
case .trigger(.next(let trigger)):
return trigger ? (buffer: [], trigger: trigger, out: current.buffer) : (buffer: current.buffer, trigger: trigger, out: [])
case .trigger(.completed):
return (buffer: [], trigger: true, out: current.buffer)
case .trigger(.error(let error)):
throw error
}
})
.flatMap { $0.out.isEmpty ? Observable.empty() : Observable.from($0.out) }
}
}
private enum Action<E> { case value(E); case trigger(Event<Bool>) }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment