pub trait SignalVecExt: SignalVec {
Show 21 methods
// Provided methods
fn map<A, F>(self, callback: F) -> Map<Self, F>
where F: FnMut(Self::Item) -> A,
Self: Sized { ... }
fn map_signal<A, F>(self, callback: F) -> MapSignal<Self, A, F>
where A: Signal,
F: FnMut(Self::Item) -> A,
Self: Sized { ... }
fn chain<S>(self, other: S) -> Chain<Self, S>
where S: SignalVec<Item = Self::Item>,
Self: Sized { ... }
fn to_signal_map<A, F>(self, callback: F) -> ToSignalMap<Self, F>
where F: FnMut(&[Self::Item]) -> A,
Self: Sized { ... }
fn to_signal_cloned(self) -> ToSignalCloned<Self>
where Self::Item: Clone,
Self: Sized { ... }
fn filter<F>(self, callback: F) -> Filter<Self, F>
where F: FnMut(&Self::Item) -> bool,
Self: Sized { ... }
fn filter_signal_cloned<A, F>(
self,
callback: F,
) -> FilterSignalCloned<Self, A, F>
where A: Signal<Item = bool>,
F: FnMut(&Self::Item) -> A,
Self: Sized { ... }
fn filter_map<A, F>(self, callback: F) -> FilterMap<Self, F>
where F: FnMut(Self::Item) -> Option<A>,
Self: Sized { ... }
fn sum(self) -> SumSignal<Self>
where Self::Item: for<'a> Sum<&'a Self::Item>,
Self: Sized { ... }
fn flatten(self) -> Flatten<Self>
where Self::Item: SignalVec,
Self: Sized { ... }
fn debug(self) -> SignalVecDebug<Self>
where Self: Sized,
Self::Item: Debug { ... }
fn sort_by_cloned<F>(self, compare: F) -> SortByCloned<Self, F>
where F: FnMut(&Self::Item, &Self::Item) -> Ordering,
Self: Sized { ... }
fn to_stream(self) -> SignalVecStream<Self>
where Self: Sized { ... }
fn for_each<U, F>(self, callback: F) -> ForEach<Self, U, F> ⓘ
where U: Future<Output = ()>,
F: FnMut(VecDiff<Self::Item>) -> U,
Self: Sized { ... }
fn len(self) -> Len<Self>
where Self: Sized { ... }
fn is_empty(self) -> IsEmpty<Self>
where Self: Sized { ... }
fn enumerate(self) -> Enumerate<Self>
where Self: Sized { ... }
fn delay_remove<A, F>(self, f: F) -> DelayRemove<Self, A, F>
where A: Future<Output = ()>,
F: FnMut(&Self::Item) -> A,
Self: Sized { ... }
fn poll_vec_change_unpin(
&mut self,
cx: &mut Context<'_>,
) -> Poll<Option<VecDiff<Self::Item>>>
where Self: Unpin + Sized { ... }
fn boxed<'a>(self) -> Pin<Box<dyn SignalVec<Item = Self::Item> + Send + 'a>>
where Self: Sized + Send + 'a { ... }
fn boxed_local<'a>(self) -> Pin<Box<dyn SignalVec<Item = Self::Item> + 'a>>
where Self: Sized + 'a { ... }
}
Provided Methods§
Sourcefn map<A, F>(self, callback: F) -> Map<Self, F>
fn map<A, F>(self, callback: F) -> Map<Self, F>
Creates a SignalVec
which uses a closure to transform the values.
When the output SignalVec
is spawned:
-
It calls the closure once for each value in
self
. The return values from the closure are put into the outputSignalVec
in the same order asself
. -
Whenever
self
changes it calls the closure for the new values, and updates the outputSignalVec
as appropriate, maintaining the same order asself
.
It is guaranteed that the closure will be called exactly once for each value in self
.
§Examples
Add 1
to each value:
let mapped = input.map(|value| value + 1);
If input
has the values [1, 2, 3, 4, 5]
then mapped
has the values [2, 3, 4, 5, 6]
Formatting to a String
:
let mapped = input.map(|value| format!("{}", value));
If input
has the values [1, 2, 3, 4, 5]
then mapped
has the values ["1", "2", "3", "4", "5"]
§Performance
This is an extremely efficient method: it is guaranteed constant time, regardless of how big self
is.
In addition, it does not do any heap allocation, and it doesn’t need to maintain any extra internal state.
The only exception is when self
notifies with VecDiff::Replace
, in which case it is linear time
(and it heap allocates a single Vec
).
fn map_signal<A, F>(self, callback: F) -> MapSignal<Self, A, F>
Sourcefn chain<S>(self, other: S) -> Chain<Self, S>
fn chain<S>(self, other: S) -> Chain<Self, S>
Chains two SignalVec
s together.
The output SignalVec
will contain all of the items in self
,
followed by all of the items in other
.
This behaves just like the Iterator::chain
method, except it will automatically keep the output SignalVec
in sync with the
two input SignalVec
s.
§Examples
// left = [1, 2, 3]
// right = [4, 5, 6]
let chained = left.chain(right);
// chained = [1, 2, 3, 4, 5, 6]
§Performance
This is a fairly efficient method: it is guaranteed constant time, regardless of how big self
or other
are.
In addition, it does not do any heap allocation, the only internal state it keeps is 2 usize
.
The only exception is when self
or other
notifies with VecDiff::Replace
or VecDiff::Clear
,
in which case it is linear time (and it heap allocates a single
VecDeque
).
fn to_signal_map<A, F>(self, callback: F) -> ToSignalMap<Self, F>
fn to_signal_cloned(self) -> ToSignalCloned<Self>
Sourcefn filter<F>(self, callback: F) -> Filter<Self, F>
fn filter<F>(self, callback: F) -> Filter<Self, F>
Creates a SignalVec
which uses a closure to determine if a value should be included or not.
When the output SignalVec
is spawned:
-
It calls the closure once for each value in
self
. The outputSignalVec
contains all of the values where the closure returnedtrue
, in the same order asself
. -
Whenever
self
changes it calls the closure for the new values, and filters the outputSignalVec
as appropriate, maintaining the same order asself
.
It is guaranteed that the closure will be called exactly once for each value in self
.
§Examples
Only include values less than 5
:
let filtered = input.filter(|value| *value < 5);
If input
has the values [3, 1, 6, 2, 0, 4, 5, 8, 9, 7]
then filtered
has the values [3, 1, 2, 0, 4]
§Performance
The performance is linear with the number of values in self
(it’s the same algorithmic
performance as Vec
).
As an example, if self
has 1,000 values and a new value is inserted, filter
will require (on
average) 1,000 operations to update its internal state. It does not call the closure while updating
its internal state.
That might sound expensive, but each individual operation is extremely fast, so it’s normally not a problem
unless self
is really huge.
fn filter_signal_cloned<A, F>( self, callback: F, ) -> FilterSignalCloned<Self, A, F>
fn filter_map<A, F>(self, callback: F) -> FilterMap<Self, F>
fn sum(self) -> SumSignal<Self>
fn debug(self) -> SignalVecDebug<Self>
Sourcefn sort_by_cloned<F>(self, compare: F) -> SortByCloned<Self, F>
fn sort_by_cloned<F>(self, compare: F) -> SortByCloned<Self, F>
Creates a SignalVec
which uses a closure to sort the values.
When the output SignalVec
is spawned:
-
It repeatedly calls the closure with two different values from
self
, and the closure must return anOrdering
, which is used to sort the values. The outputSignalVec
then contains the values in sorted order. -
Whenever
self
changes it calls the closure repeatedly, and sorts the outputSignalVec
based upon theOrdering
.
This method is intentionally very similar to the slice::sort_by
method, except it doesn’t mutate self
(it returns a new SignalVec
).
Just like slice::sort_by
, the
sorting is stable: if the closure returns Ordering::Equal
, then the order will be based upon the
order in self
.
The reason why it has the _cloned
suffix is because it calls clone
on the values from self
. This is necessary in order to maintain its internal state
while also simultaneously passing the values to the output SignalVec
.
You can avoid the cost of cloning by using .map(Rc::new)
or .map(Arc::new)
to wrap the values in
Rc
or Arc
,
like this:
use std::rc::Rc;
let sorted = input.map(Rc::new).sort_by_cloned(Ord::cmp);
However, this heap allocates each individual value, so it should only be done when the cost of cloning is expensive. You should benchmark and profile so you know which one is faster for your particular program!
§Requirements
It is invalid for the sort order to dynamically change. If dynamic sorting is needed, you can use
map_signal
:
let sorted = input
.map_signal(|x| {
returns_a_signal(x)
})
.sort_by_cloned(|x, y| {
// ...
});
§Examples
Sort using the standard Ord
implementation:
let sorted = input.sort_by_cloned(Ord::cmp);
If input
has the values [3, 1, 6, 2, 0, 4, 5, 8, 9, 7]
then sorted
has the values [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Sort using a custom function:
let sorted = input.sort_by_cloned(|left, right| left.cmp(right).reverse());
If input
has the values [3, 1, 6, 2, 0, 4, 5, 8, 9, 7]
then sorted
has the values [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
§Performance
It has the same logarithmic performance as slice::sort_by
,
except it’s slower because it needs to keep track of extra internal state.
As an example, if self
has 1,000 values and a new value is inserted, then sort_by_cloned
will require
(on average) ~2,010 operations to update its internal state. It does not call the closure while updating
its internal state.
That might sound expensive, but each individual operation is extremely fast, so it’s normally not a problem
unless self
is really huge.
fn to_stream(self) -> SignalVecStream<Self>where
Self: Sized,
fn for_each<U, F>(self, callback: F) -> ForEach<Self, U, F> ⓘ
fn len(self) -> Len<Self>where
Self: Sized,
fn is_empty(self) -> IsEmpty<Self>where
Self: Sized,
fn enumerate(self) -> Enumerate<Self>where
Self: Sized,
fn delay_remove<A, F>(self, f: F) -> DelayRemove<Self, A, F>
Sourcefn poll_vec_change_unpin(
&mut self,
cx: &mut Context<'_>,
) -> Poll<Option<VecDiff<Self::Item>>>
fn poll_vec_change_unpin( &mut self, cx: &mut Context<'_>, ) -> Poll<Option<VecDiff<Self::Item>>>
A convenience for calling SignalVec::poll_vec_change
on Unpin
types.