use std::future;
use either::Either;
use futures_core::Stream;
use futures_util::{stream::select, StreamExt};
pub fn combine_latest<T1: Clone, T2: Clone>(
s1: impl Stream<Item = T1>,
s2: impl Stream<Item = T2>,
) -> impl Stream<Item = (T1, T2)> {
combine_latest_optional(s1, s2).filter_map(|(v1, v2)| future::ready(v1.zip(v2)))
}
pub fn combine_latest_optional<T1: Clone, T2: Clone>(
s1: impl Stream<Item = T1>,
s2: impl Stream<Item = T2>,
) -> impl Stream<Item = (Option<T1>, Option<T2>)> {
let mut current1 = None;
let mut current2 = None;
select(s1.map(Either::Left), s2.map(Either::Right)).map(move |either| {
match either {
Either::Left(l) => current1 = Some(l),
Either::Right(r) => current2 = Some(r),
};
(current1.clone(), current2.clone())
})
}