pub trait SignalExt: Signal {
Show 25 methods // Provided methods 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 eq(self, value: Self::Item) -> Eq<Self> where Self::Item: PartialEq, Self: Sized { ... } fn neq(self, value: Self::Item) -> Neq<Self> where Self::Item: PartialEq, Self: Sized { ... } fn dedupe_map<A, B>(self, callback: B) -> DedupeMap<Self, B> where B: FnMut(&mut Self::Item) -> A, Self::Item: PartialEq, Self: Sized { ... } fn dedupe(self) -> Dedupe<Self> where Self::Item: PartialEq, Self: Sized { ... } fn dedupe_cloned(self) -> DedupeCloned<Self> where Self::Item: PartialEq, 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 throttle<A, B>(self, callback: B) -> Throttle<Self, A, B> where A: Future<Output = ()>, B: FnMut() -> 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 sample_stream_cloned<A>(self, stream: A) -> SampleStreamCloned<Self, A> where A: Stream, A::Item: Clone, 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 debug(self) -> SignalDebug<Self> where Self: Sized, Self::Item: Debug { ... } fn broadcast(self) -> Broadcaster<Self> where Self: Sized { ... } fn poll_change_unpin( &mut self, cx: &mut Context<'_> ) -> Poll<Option<Self::Item>> where Self: Unpin + Sized { ... } fn boxed<'a>(self) -> Pin<Box<dyn Signal<Item = Self::Item> + Send + 'a>> where Self: Sized + Send + 'a { ... } fn boxed_local<'a>(self) -> Pin<Box<dyn Signal<Item = Self::Item> + 'a>> where Self: Sized + 'a { ... }
}

Provided Methods§

source

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.

source

fn to_future(self) -> SignalFuture<Self> where Self: Sized,

source

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.

source

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

source

fn eq(self, value: Self::Item) -> Eq<Self>where Self::Item: PartialEq, Self: Sized,

source

fn neq(self, value: Self::Item) -> Neq<Self>where Self::Item: PartialEq, Self: Sized,

source

fn dedupe_map<A, B>(self, callback: B) -> DedupeMap<Self, B>where B: FnMut(&mut Self::Item) -> A, Self::Item: PartialEq, 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.

source

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

source

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

source

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.

source

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.

source

fn throttle<A, B>(self, callback: B) -> Throttle<Self, A, B>where A: Future<Output = ()>, B: FnMut() -> A, Self: Sized,

Creates a Signal which delays updates until a Future finishes.

This can be used to throttle a Signal so that it only updates once every X seconds.

If multiple updates happen while it’s being delayed, it will only output the most recent value.

Examples

Wait 1 second between each update:

let output = input.throttle(|| sleep(1_000));
Performance

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

source

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.

source

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

source

fn switch_signal_vec<A, F>(self, callback: F) -> SwitchSignalVec<Self, A, F>where A: SignalVec, F: FnMut(Self::Item) -> A, Self: Sized,

source

fn sample_stream_cloned<A>(self, stream: A) -> SampleStreamCloned<Self, A>where A: Stream, A::Item: Clone, Self: Sized,

Creates a Stream which samples the value of self whenever the Stream has a new value.

Performance

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

source

fn for_each<U, F>(self, callback: F) -> ForEach<Self, U, F> where U: Future<Output = ()>, F: FnMut(Self::Item) -> U, Self: Sized,

source

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

source

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

source

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

source

fn debug(self) -> SignalDebug<Self>where Self: Sized, Self::Item: Debug,

source

fn broadcast(self) -> Broadcaster<Self>where Self: Sized,

A convenience method for calling Broadcaster::new.

This allows you to clone / split a Signal into multiple Signals.

See the documentation for Broadcaster for more details.

source

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.

source

fn boxed<'a>(self) -> Pin<Box<dyn Signal<Item = Self::Item> + Send + 'a>>where Self: Sized + Send + 'a,

source

fn boxed_local<'a>(self) -> Pin<Box<dyn Signal<Item = Self::Item> + 'a>>where Self: Sized + 'a,

Implementors§

source§

impl<T> SignalExt for Twhere T: Signal + ?Sized,