[][src]Trait futures_signals::signal_vec::SignalVecExt

pub trait SignalVecExt: SignalVec {
    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 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 sum(self) -> SumSignal<Self>
    where
        Self::Item: for<'a> Sum<&'a Self::Item>,
        Self: Sized
, { ... }
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 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
, { ... } }

Provided methods

fn map<A, F>(self, callback: F) -> Map<Self, F> where
    F: FnMut(Self::Item) -> A,
    Self: Sized

Creates a SignalVec which uses a closure to transform the values.

When the output SignalVec is spawned:

  1. It calls the closure once for each value in self. The return values from the closure are put into the output SignalVec in the same order as self.

  2. Whenever self changes it calls the closure for the new values, and updates the output SignalVec as appropriate, maintaining the same order as self.

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> where
    A: Signal,
    F: FnMut(Self::Item) -> A,
    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

Creates a SignalVec which uses a closure to determine if a value should be included or not.

When the output SignalVec is spawned:

  1. It calls the closure once for each value in self. The output SignalVec contains all of the values where the closure returned true, in the same order as self.

  2. Whenever self changes it calls the closure for the new values, and filters the output SignalVec as appropriate, maintaining the same order as self.

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> where
    A: Signal<Item = bool>,
    F: FnMut(&Self::Item) -> A,
    Self: Sized

fn sum(self) -> SumSignal<Self> where
    Self::Item: for<'a> Sum<&'a Self::Item>,
    Self: Sized

fn sort_by_cloned<F>(self, compare: F) -> SortByCloned<Self, F> where
    F: FnMut(&Self::Item, &Self::Item) -> Ordering,
    Self: Sized

Creates a SignalVec which uses a closure to sort the values.

When the output SignalVec is spawned:

  1. It repeatedly calls the closure with two different values from self, and the closure must return an Ordering, which is used to sort the values. The output SignalVec then contains the values in sorted order.

  2. Whenever self changes it calls the closure repeatedly, and sorts the output SignalVec based upon the Ordering.

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!

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

Important traits for ForEach<A, B, C>
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 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

A convenience for calling SignalVec::poll_vec_change on Unpin types.

Loading content...

Implementors

impl<T: ?Sized> SignalVecExt for T where
    T: SignalVec
[src]

Loading content...