Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jplatte/eyeball
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 69f4f52eb48b0914d551caa733a7b93dbbda2894
Choose a base ref
..
head repository: jplatte/eyeball
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: e5d9883a4ae5c2a0ad8afbb81918a1ff39868704
Choose a head ref
6 changes: 4 additions & 2 deletions eyeball-im-util/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# Unreleased

- Add the `RLimit` adapter
- Improve the documentation of `Limit` by adding an example
- Add the `Tail` adapter
- Improve the documentation of `Head` by adding an example
- Rename `Limit` to `Head`, along with all the similar methods, like
`VectorObserverExt::limit` which becomes `VectorObserverExt::head` and so on.

# 0.7.0

20 changes: 10 additions & 10 deletions eyeball-im-util/src/vector.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
//! Utilities around [`ObservableVector`][eyeball_im::ObservableVector].
mod filter;
mod limit;
mod head;
mod ops;
mod rlimit;
mod sort;
mod tail;
mod traits;

use eyeball_im::VectorDiff;
@@ -13,9 +13,9 @@ use futures_core::Stream;
use self::ops::{VectorDiffContainerFamilyMember, VectorDiffContainerOps};
pub use self::{
filter::{Filter, FilterMap},
limit::{EmptyLimitStream, Limit},
rlimit::RLimit,
head::{EmptyLimitStream, Head},
sort::{Sort, SortBy, SortByKey},
tail::Tail,
traits::{
BatchedVectorSubscriber, VectorDiffContainer, VectorObserver, VectorObserverExt,
VectorSubscriberExt,
@@ -43,14 +43,14 @@ type VectorDiffContainerStreamFamily<S> =
type VectorDiffContainerDiff<S> = VectorDiff<VectorDiffContainerStreamElement<S>>;

/// Type alias for extracting the buffer type from a stream of
/// [`VectorDiffContainer`]s' `LimitBuf`.
type VectorDiffContainerStreamLimitBuf<S> =
<<S as Stream>::Item as VectorDiffContainerOps<VectorDiffContainerStreamElement<S>>>::LimitBuf;
/// [`VectorDiffContainer`]s' `HeadBuf`.
type VectorDiffContainerStreamHeadBuf<S> =
<<S as Stream>::Item as VectorDiffContainerOps<VectorDiffContainerStreamElement<S>>>::HeadBuf;

/// Type alias for extracting the buffer type from a stream of
/// [`VectorDiffContainer`]s' `RLimitBuf`.
type VectorDiffContainerStreamRLimitBuf<S> =
<<S as Stream>::Item as VectorDiffContainerOps<VectorDiffContainerStreamElement<S>>>::RLimitBuf;
/// [`VectorDiffContainer`]s' `TailBuf`.
type VectorDiffContainerStreamTailBuf<S> =
<<S as Stream>::Item as VectorDiffContainerOps<VectorDiffContainerStreamElement<S>>>::TailBuf;

/// Type alias for extracting the buffer type from a stream of
/// [`VectorDiffContainer`]s' `SortBuf`.
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ use std::{

use super::{
VectorDiffContainer, VectorDiffContainerOps, VectorDiffContainerStreamElement,
VectorDiffContainerStreamLimitBuf, VectorObserver,
VectorDiffContainerStreamHeadBuf, VectorObserver,
};
use eyeball_im::VectorDiff;
use futures_core::Stream;
@@ -18,12 +18,12 @@ use pin_project_lite::pin_project;
pin_project! {
/// A [`VectorDiff`] stream adapter that presents a limited view of the
/// underlying [`ObservableVector`]'s items. The view starts from index 0.
/// This is the opposite of [`RLimit`](super::RLimit), which starts from
/// the end.
/// This is the opposite of [`Tail`](super::Tail), which starts from the
/// end.
///
/// For example, let `S` be a `Stream<Item = VectorDiff>`. The [`Vector`]
/// represented by `S` can have any length, but one may want to virtually
/// _limit_ this `Vector` to a certain size. Then this `Limit` adapter is
/// _limit_ this `Vector` to a certain size. Then this `Head` adapter is
/// appropriate.
///
/// An internal buffered vector is kept so that the adapter knows which
@@ -44,7 +44,7 @@ pin_project! {
///
/// // Our vector.
/// let mut ob = ObservableVector::<char>::new();
/// let (values, mut sub) = ob.subscribe().limit(3);
/// let (values, mut sub) = ob.subscribe().head(3);
///
/// assert!(values.is_empty());
/// assert_pending!(sub);
@@ -79,8 +79,8 @@ pin_project! {
/// ```
///
/// [`ObservableVector`]: eyeball_im::ObservableVector
#[project = LimitProj]
pub struct Limit<S, L>
#[project = HeadProj]
pub struct Head<S, L>
where
S: Stream,
S::Item: VectorDiffContainer,
@@ -109,16 +109,16 @@ pin_project! {
// with a limit of 2 on top: if an item is popped at the front then 10
// is removed, but 12 has to be pushed back as it "enters" the "view".
// That second `PushBack` diff is buffered here.
ready_values: VectorDiffContainerStreamLimitBuf<S>,
ready_values: VectorDiffContainerStreamHeadBuf<S>,
}
}

impl<S> Limit<S, EmptyLimitStream>
impl<S> Head<S, EmptyLimitStream>
where
S: Stream,
S::Item: VectorDiffContainer,
{
/// Create a new [`Limit`] with the given (unlimited) initial values,
/// Create a new [`Head`] with the given (unlimited) initial values,
/// stream of `VectorDiff` updates for those values, and a fixed limit.
///
/// Returns the truncated initial values as well as a stream of updates that
@@ -132,20 +132,20 @@ where
}
}

impl<S, L> Limit<S, L>
impl<S, L> Head<S, L>
where
S: Stream,
S::Item: VectorDiffContainer,
L: Stream<Item = usize>,
{
/// Create a new [`Limit`] with the given (unlimited) initial values, stream
/// Create a new [`Head`] with the given (unlimited) initial values, stream
/// of `VectorDiff` updates for those values, and a stream of limits.
///
/// This is equivalent to `dynamic_with_initial_limit` where the
/// `initial_limit` is 0, except that it doesn't return the limited
/// vector as it would be empty anyways.
///
/// Note that the returned `Limit` won't produce anything until the first
/// Note that the returned `Head` won't produce anything until the first
/// limit is produced by the limit stream.
pub fn dynamic(
initial_values: Vector<VectorDiffContainerStreamElement<S>>,
@@ -161,7 +161,7 @@ where
}
}

/// Create a new [`Limit`] with the given (unlimited) initial values, stream
/// Create a new [`Head`] with the given (unlimited) initial values, stream
/// of `VectorDiff` updates for those values, and an initial limit as well
/// as a stream of new limits.
pub fn dynamic_with_initial_limit(
@@ -187,7 +187,7 @@ where
}
}

impl<S, L> Stream for Limit<S, L>
impl<S, L> Stream for Head<S, L>
where
S: Stream,
S::Item: VectorDiffContainer,
@@ -200,7 +200,7 @@ where
}
}

impl<S, L> VectorObserver<VectorDiffContainerStreamElement<S>> for Limit<S, L>
impl<S, L> VectorObserver<VectorDiffContainerStreamElement<S>> for Head<S, L>
where
S: Stream,
S::Item: VectorDiffContainer,
@@ -213,7 +213,7 @@ where
}
}

impl<S, L> LimitProj<'_, S, L>
impl<S, L> HeadProj<'_, S, L>
where
S: Stream,
S::Item: VectorDiffContainer,
@@ -222,7 +222,7 @@ where
fn poll_next(&mut self, cx: &mut task::Context<'_>) -> Poll<Option<S::Item>> {
loop {
// First off, if any values are ready, return them.
if let Some(value) = S::Item::pop_from_limit_buf(self.ready_values) {
if let Some(value) = S::Item::pop_from_head_buf(self.ready_values) {
return Poll::Ready(Some(value));
}

@@ -244,7 +244,7 @@ where
};

// Consume and apply the diffs if possible.
let ready = diffs.push_into_limit_buf(self.ready_values, |diff| {
let ready = diffs.push_into_head_buf(self.ready_values, |diff| {
let limit = *self.limit;
let prev_len = self.buffered_vector.len();

58 changes: 29 additions & 29 deletions eyeball-im-util/src/vector/ops.rs
Original file line number Diff line number Diff line change
@@ -4,8 +4,8 @@ use smallvec::SmallVec;

pub trait VectorDiffContainerOps<T>: Sized {
type Family: VectorDiffContainerFamily;
type LimitBuf: Default;
type RLimitBuf: Default;
type HeadBuf: Default;
type TailBuf: Default;
type SortBuf: Default;

fn from_item(vector_diff: VectorDiff<T>) -> Self;
@@ -15,23 +15,23 @@ pub trait VectorDiffContainerOps<T>: Sized {
f: impl FnMut(VectorDiff<T>) -> Option<VectorDiff<U>>,
) -> Option<VectorDiffContainerFamilyMember<Self::Family, U>>;

fn push_into_limit_buf(
fn push_into_head_buf(
self,
buffer: &mut Self::LimitBuf,
buffer: &mut Self::HeadBuf,
map_diffs: impl FnMut(VectorDiff<T>) -> ArrayVec<VectorDiff<T>, 2>,
) -> Option<Self>;

fn pop_from_limit_buf(buffer: &mut Self::LimitBuf) -> Option<Self>;
fn pop_from_head_buf(buffer: &mut Self::HeadBuf) -> Option<Self>;

fn push_into_rlimit_buf(
fn push_into_tail_buf(
self,
buffer: &mut Self::RLimitBuf,
buffer: &mut Self::TailBuf,
map_diffs: impl FnMut(VectorDiff<T>) -> SmallVec<[VectorDiff<T>; 2]>,
) -> Option<Self>;

fn extend_rlimit_buf(diffs: Vec<VectorDiff<T>>, buffer: &mut Self::RLimitBuf) -> Option<Self>;
fn extend_tail_buf(diffs: Vec<VectorDiff<T>>, buffer: &mut Self::TailBuf) -> Option<Self>;

fn pop_from_rlimit_buf(buffer: &mut Self::RLimitBuf) -> Option<Self>;
fn pop_from_tail_buf(buffer: &mut Self::TailBuf) -> Option<Self>;

fn push_into_sort_buf(
self,
@@ -47,8 +47,8 @@ pub type VectorDiffContainerFamilyMember<F, U> = <F as VectorDiffContainerFamily

impl<T> VectorDiffContainerOps<T> for VectorDiff<T> {
type Family = VectorDiffFamily;
type LimitBuf = Option<VectorDiff<T>>;
type RLimitBuf = SmallVec<[VectorDiff<T>; 2]>;
type HeadBuf = Option<VectorDiff<T>>;
type TailBuf = SmallVec<[VectorDiff<T>; 2]>;
type SortBuf = SmallVec<[VectorDiff<T>; 2]>;

fn from_item(vector_diff: VectorDiff<T>) -> Self {
@@ -62,12 +62,12 @@ impl<T> VectorDiffContainerOps<T> for VectorDiff<T> {
f(self)
}

fn push_into_limit_buf(
fn push_into_head_buf(
self,
buffer: &mut Self::LimitBuf,
buffer: &mut Self::HeadBuf,
mut map_diffs: impl FnMut(VectorDiff<T>) -> ArrayVec<VectorDiff<T>, 2>,
) -> Option<Self> {
assert!(buffer.is_none(), "buffer must be None when calling push_into_limit_buf");
assert!(buffer.is_none(), "buffer must be None when calling push_into_head_buf");

let mut diffs = map_diffs(self);

@@ -80,29 +80,29 @@ impl<T> VectorDiffContainerOps<T> for VectorDiff<T> {
}
}

fn pop_from_limit_buf(buffer: &mut Self::LimitBuf) -> Option<Self> {
fn pop_from_head_buf(buffer: &mut Self::HeadBuf) -> Option<Self> {
buffer.take()
}

fn push_into_rlimit_buf(
fn push_into_tail_buf(
self,
buffer: &mut Self::RLimitBuf,
buffer: &mut Self::TailBuf,
mut map_diffs: impl FnMut(VectorDiff<T>) -> SmallVec<[VectorDiff<T>; 2]>,
) -> Option<Self> {
buffer.insert_many(0, map_diffs(self).into_iter().rev());

buffer.pop()
}

fn extend_rlimit_buf(diffs: Vec<VectorDiff<T>>, buffer: &mut Self::RLimitBuf) -> Option<Self> {
fn extend_tail_buf(diffs: Vec<VectorDiff<T>>, buffer: &mut Self::TailBuf) -> Option<Self> {
// We cannot pop front on a `SmallVec`. We store all `diffs` in reverse order to
// pop from it.
buffer.insert_many(0, diffs.into_iter().rev());

buffer.pop()
}

fn pop_from_rlimit_buf(buffer: &mut Self::RLimitBuf) -> Option<Self> {
fn pop_from_tail_buf(buffer: &mut Self::TailBuf) -> Option<Self> {
buffer.pop()
}

@@ -136,8 +136,8 @@ impl<T> VectorDiffContainerOps<T> for VectorDiff<T> {

impl<T> VectorDiffContainerOps<T> for Vec<VectorDiff<T>> {
type Family = VecVectorDiffFamily;
type LimitBuf = ();
type RLimitBuf = ();
type HeadBuf = ();
type TailBuf = ();
type SortBuf = ();

fn from_item(vector_diff: VectorDiff<T>) -> Self {
@@ -157,9 +157,9 @@ impl<T> VectorDiffContainerOps<T> for Vec<VectorDiff<T>> {
}
}

fn push_into_limit_buf(
fn push_into_head_buf(
self,
_buffer: &mut Self::LimitBuf,
_buffer: &mut Self::HeadBuf,
map_diffs: impl FnMut(VectorDiff<T>) -> ArrayVec<VectorDiff<T>, 2>,
) -> Option<Self> {
let res: Vec<_> = self.into_iter().flat_map(map_diffs).collect();
@@ -171,13 +171,13 @@ impl<T> VectorDiffContainerOps<T> for Vec<VectorDiff<T>> {
}
}

fn pop_from_limit_buf(_: &mut Self::LimitBuf) -> Option<Self> {
fn pop_from_head_buf(_: &mut Self::HeadBuf) -> Option<Self> {
None
}

fn push_into_rlimit_buf(
fn push_into_tail_buf(
self,
_buffer: &mut Self::RLimitBuf,
_buffer: &mut Self::TailBuf,
map_diffs: impl FnMut(VectorDiff<T>) -> SmallVec<[VectorDiff<T>; 2]>,
) -> Option<Self> {
let res: Vec<_> = self.into_iter().flat_map(map_diffs).collect();
@@ -189,15 +189,15 @@ impl<T> VectorDiffContainerOps<T> for Vec<VectorDiff<T>> {
}
}

fn extend_rlimit_buf(diffs: Vec<VectorDiff<T>>, _buffer: &mut Self::RLimitBuf) -> Option<Self> {
fn extend_tail_buf(diffs: Vec<VectorDiff<T>>, _buffer: &mut Self::TailBuf) -> Option<Self> {
if diffs.is_empty() {
None
} else {
Some(diffs)
}
}

fn pop_from_rlimit_buf(_buffer: &mut Self::RLimitBuf) -> Option<Self> {
fn pop_from_tail_buf(_buffer: &mut Self::TailBuf) -> Option<Self> {
None
}

@@ -215,7 +215,7 @@ impl<T> VectorDiffContainerOps<T> for Vec<VectorDiff<T>> {
}
}

fn pop_from_sort_buf(_: &mut Self::LimitBuf) -> Option<Self> {
fn pop_from_sort_buf(_: &mut Self::HeadBuf) -> Option<Self> {
None
}
}
Loading