[][src]Trait futures_signals::signal::SignalExt

pub trait SignalExt: Signal {
    fn to_stream(self) -> SignalStream<Self>
    where
        Self: Sized
, { ... }
fn to_future(self) -> SignalFuture<Self>
    where
        Self: Sized
, { ... }
fn map<A, B>(self, callback: B) -> Map<Self, B>
    where
        B: FnMut(Self::Item) -> A,
        Self: Sized
, { ... }
fn inspect<A>(self, callback: A) -> Inspect<Self, A>
    where
        A: FnMut(&Self::Item),
        Self: Sized
, { ... }
fn dedupe_map<A, B>(self, callback: B) -> DedupeMap<Self, B>
    where
        B: FnMut(&mut Self::Item) -> A,
        Self: Sized
, { ... }
fn dedupe(self) -> Dedupe<Self>
    where
        Self: Sized
, { ... }
fn dedupe_cloned(self) -> DedupeCloned<Self>
    where
        Self: Sized
, { ... }
fn map_future<A, B>(self, callback: B) -> MapFuture<Self, A, B>
    where
        A: Future,
        B: FnMut(Self::Item) -> A,
        Self: Sized
, { ... }
fn filter_map<A, B>(self, callback: B) -> FilterMap<Self, B>
    where
        B: FnMut(Self::Item) -> Option<A>,
        Self: Sized
, { ... }
fn flatten(self) -> Flatten<Self>
    where
        Self::Item: Signal,
        Self: Sized
, { ... }
fn switch<A, B>(self, callback: B) -> Switch<Self, A, B>
    where
        A: Signal,
        B: FnMut(Self::Item) -> A,
        Self: Sized
, { ... }
fn switch_signal_vec<A, F>(self, callback: F) -> SwitchSignalVec<Self, A, F>
    where
        A: SignalVec,
        F: FnMut(Self::Item) -> A,
        Self: Sized
, { ... }
fn for_each<U, F>(self, callback: F) -> ForEach<Self, U, F>
    where
        U: Future<Output = ()>,
        F: FnMut(Self::Item) -> U,
        Self: Sized
, { ... }
fn to_signal_vec(self) -> SignalSignalVec<Self>
    where
        Self: Sized
, { ... }
fn wait_for(self, value: Self::Item) -> WaitFor<Self>
    where
        Self::Item: PartialEq,
        Self: Sized
, { ... }
fn first(self) -> First<Self>
    where
        Self: Sized
, { ... }
fn poll_change_unpin(
        &mut self,
        cx: &mut Context
    ) -> Poll<Option<Self::Item>>
    where
        Self: Unpin + Sized
, { ... } }

Provided methods

fn to_stream(self) -> SignalStream<Self> where
    Self: Sized

Creates a Stream which contains the values of self.

When the output Stream is spawned:

  1. It immediately outputs the current value of self.

  2. Whenever self changes it outputs the new value of self.

Like all of the Signal methods, to_stream might skip intermediate changes. So you cannot rely upon it containing every intermediate change. But you can rely upon it always containing the most recent change.

Performance

This is extremely efficient: it is guaranteed constant time, and it does not do any heap allocation.

Important traits for SignalFuture<A>
fn to_future(self) -> SignalFuture<Self> where
    Self: Sized

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

Creates a Signal which uses a closure to transform the value.

When the output Signal is spawned:

  1. It calls the closure with the current value of self.

  2. Then it puts the return value of the closure into the output Signal.

  3. Whenever self changes it repeats the above steps.

    This happens automatically and efficiently.

It will call the closure at most once for each change in self.

Like all of the Signal methods, map might skip intermediate changes. So you cannot rely upon the closure being called for every intermediate change. But you can rely upon it always being called with the most recent change.

Examples

Add 1 to the value:

let mapped = input.map(|value| value + 1);

mapped will always contain the current value of input, except with 1 added to it.

If input has the value 10, then mapped will have the value 11.

If input has the value 5, then mapped will have the value 6, etc.


Formatting to a String:

let mapped = input.map(|value| format!("{}", value));

mapped will always contain the current value of input, except formatted as a String.

If input has the value 10, then mapped will have the value "10".

If input has the value 5, then mapped will have the value "5", etc.

Performance

This is extremely efficient: it is guaranteed constant time, and it does not do any heap allocation.

fn inspect<A>(self, callback: A) -> Inspect<Self, A> where
    A: FnMut(&Self::Item),
    Self: Sized

fn dedupe_map<A, B>(self, callback: B) -> DedupeMap<Self, B> where
    B: FnMut(&mut Self::Item) -> A,
    Self: Sized

Creates a Signal which uses a closure to transform the value.

This is exactly the same as map, except:

  1. It calls the closure with a mutable reference to the input value.

  2. If the new input value is the same as the old input value, it will not call the closure, instead it will completely ignore the new value, like as if it never happened.

    It uses the PartialEq implementation to determine whether the new value is the same as the old value.

    It only keeps track of the most recent value: that means that it won't call the closure for consecutive duplicates, however it will call the closure for non-consecutive duplicates.

Because dedupe_map has the same behavior as map, it is useful solely as a performance optimization.

Performance

The performance is the same as map, except with an additional call to eq.

If the eq call is fast, then dedupe_map can be faster than map, because it doesn't call the closure when the new and old values are the same, and it also doesn't update any child Signals.

On the other hand, if the eq call is slow, then dedupe_map is probably slower than map.

fn dedupe(self) -> Dedupe<Self> where
    Self: Sized

fn dedupe_cloned(self) -> DedupeCloned<Self> where
    Self: Sized

fn map_future<A, B>(self, callback: B) -> MapFuture<Self, A, B> where
    A: Future,
    B: FnMut(Self::Item) -> A,
    Self: Sized

Creates a Signal which uses a closure to asynchronously transform the value.

When the output Signal is spawned:

  1. It calls the closure with the current value of self.

  2. The closure returns a Future. It waits for that Future to finish, and then it puts the return value of the Future into the output Signal.

  3. Whenever self changes it repeats the above steps.

It will call the closure at most once for each change in self.

Because Signals must always have a current value, if the Future is not ready yet, then the output Signal will start with the value None. When the Future finishes it then changes to Some. This can be used to detect whether the Future has finished or not.

If self changes before the old Future is finished, it will cancel the old Future. That means if self changes faster than the Future, then it will never output any values.

Like all of the Signal methods, map_future might skip intermediate changes. So you cannot rely upon the closure being called for every intermediate change. But you can rely upon it always being called with the most recent change.

Examples

Call an asynchronous network API whenever the input changes:

let mapped = input.map_future(|value| call_network_api(value));

Performance

This is extremely efficient: it does not do any heap allocation, and it has very little overhead.

Of course the performance will also depend upon the Future which is returned from the closure.

fn filter_map<A, B>(self, callback: B) -> FilterMap<Self, B> where
    B: FnMut(Self::Item) -> Option<A>,
    Self: Sized

Creates a Signal which uses a closure to filter and transform the value.

When the output Signal is spawned:

  1. The output Signal starts with the value None.

  2. It calls the closure with the current value of self.

  3. If the closure returns Some, then it puts the return value of the closure into the output Signal.

  4. If the closure returns None, then it does nothing.

  5. Whenever self changes it repeats steps 2 - 4.

The output Signal will only be None for the initial value. After that it will always be Some.

If the closure returns Some for the initial value, then the output Signal will never be None.

It will call the closure at most once for each change in self.

Like all of the Signal methods, filter_map might skip intermediate changes. So you cannot rely upon the closure being called for every intermediate change. But you can rely upon it always being called with the most recent change.

Examples

Add 1 to the value, but only if the value is less than 5:

let mapped = input.filter_map(|value| {
    if value < 5 {
        Some(value + 1)

    } else {
        None
    }
});

If the initial value of input is 5 or greater then mapped will be None.

If the current value of input is 5 or greater then mapped will keep its old value.

Otherwise mapped will be Some(input + 1).

Performance

This is extremely efficient: it does not do any heap allocation, and it has very little overhead.

fn flatten(self) -> Flatten<Self> where
    Self::Item: Signal,
    Self: Sized

Creates a Signal which flattens self.

When the output Signal is spawned:

  1. It retrieves the current value of self (this value is also a Signal).

  2. Then it puts the current value of the inner Signal into the output Signal.

  3. Whenever the inner Signal changes it puts the new value into the output Signal.

  4. Whenever self changes it repeats the above steps.

    This happens automatically and efficiently.

Like all of the Signal methods, flatten might skip intermediate changes. So you cannot rely upon it containing every intermediate change. But you can rely upon it always containing the most recent change.

Performance

This is very efficient: it is guaranteed constant time, and it does not do any heap allocation.

fn switch<A, B>(self, callback: B) -> Switch<Self, A, B> where
    A: Signal,
    B: FnMut(Self::Item) -> A,
    Self: Sized

fn switch_signal_vec<A, F>(self, callback: F) -> SwitchSignalVec<Self, A, F> where
    A: SignalVec,
    F: FnMut(Self::Item) -> A,
    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(Self::Item) -> U,
    Self: Sized

fn to_signal_vec(self) -> SignalSignalVec<Self> where
    Self: Sized

Important traits for WaitFor<A>
fn wait_for(self, value: Self::Item) -> WaitFor<Self> where
    Self::Item: PartialEq,
    Self: Sized

fn first(self) -> First<Self> where
    Self: Sized

fn poll_change_unpin(&mut self, cx: &mut Context) -> Poll<Option<Self::Item>> where
    Self: Unpin + Sized

A convenience for calling Signal::poll_change on Unpin types.

Loading content...

Implementors

impl<T: ?Sized> SignalExt for T where
    T: Signal
[src]

Loading content...