pub trait SignalExt: Signal {
Show 26 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 stop_if<F>(self, test: F) -> StopIf<Self, F>
where F: FnMut(&Self::Item) -> bool,
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§
Sourcefn to_stream(self) -> SignalStream<Self>where
Self: Sized,
fn to_stream(self) -> SignalStream<Self>where
Self: Sized,
Creates a Stream
which contains the values of self
.
When the output Stream
is spawned:
-
It immediately outputs the current value of
self
. -
Whenever
self
changes it outputs the new value ofself
.
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.
fn to_future(self) -> SignalFuture<Self> ⓘwhere
Self: Sized,
Sourcefn map<A, B>(self, callback: B) -> Map<Self, B>
fn map<A, B>(self, callback: B) -> Map<Self, B>
Creates a Signal
which uses a closure to transform the value.
When the output Signal
is spawned:
-
It calls the closure with the current value of
self
. -
Then it puts the return value of the closure into the output
Signal
. -
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>
fn eq(self, value: Self::Item) -> Eq<Self>
fn neq(self, value: Self::Item) -> Neq<Self>
Sourcefn dedupe_map<A, B>(self, callback: B) -> DedupeMap<Self, B>
fn dedupe_map<A, B>(self, callback: B) -> DedupeMap<Self, B>
Creates a Signal
which uses a closure to transform the value.
This is exactly the same as map
, except:
-
It calls the closure with a mutable reference to the input value.
-
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>
fn dedupe_cloned(self) -> DedupeCloned<Self>
Sourcefn map_future<A, B>(self, callback: B) -> MapFuture<Self, A, B>
fn map_future<A, B>(self, callback: B) -> MapFuture<Self, A, B>
Creates a Signal
which uses a closure to asynchronously transform the value.
When the output Signal
is spawned:
-
It calls the closure with the current value of
self
. -
The closure returns a
Future
. It waits for thatFuture
to finish, and then it puts the return value of theFuture
into the outputSignal
. -
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.
Sourcefn filter_map<A, B>(self, callback: B) -> FilterMap<Self, B>
fn filter_map<A, B>(self, callback: B) -> FilterMap<Self, B>
Creates a Signal
which uses a closure to filter and transform the value.
When the output Signal
is spawned:
-
The output
Signal
starts with the valueNone
. -
It calls the closure with the current value of
self
. -
If the closure returns
Some
, then it puts the return value of the closure into the outputSignal
. -
If the closure returns
None
, then it does nothing. -
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.
Sourcefn throttle<A, B>(self, callback: B) -> Throttle<Self, A, B>
fn throttle<A, B>(self, callback: B) -> Throttle<Self, A, B>
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.
Sourcefn flatten(self) -> Flatten<Self>
fn flatten(self) -> Flatten<Self>
Creates a Signal
which flattens self
.
When the output Signal
is spawned:
-
It retrieves the current value of
self
(this value is also aSignal
). -
Then it puts the current value of the inner
Signal
into the outputSignal
. -
Whenever the inner
Signal
changes it puts the new value into the outputSignal
. -
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>
fn switch_signal_vec<A, F>(self, callback: F) -> SwitchSignalVec<Self, A, F>
Sourcefn sample_stream_cloned<A>(self, stream: A) -> SampleStreamCloned<Self, A>
fn sample_stream_cloned<A>(self, stream: A) -> SampleStreamCloned<Self, A>
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.
fn for_each<U, F>(self, callback: F) -> ForEach<Self, U, F> ⓘ
fn to_signal_vec(self) -> SignalSignalVec<Self>where
Self: Sized,
fn wait_for(self, value: Self::Item) -> WaitFor<Self> ⓘ
fn first(self) -> First<Self>where
Self: Sized,
Sourcefn stop_if<F>(self, test: F) -> StopIf<Self, F>
fn stop_if<F>(self, test: F) -> StopIf<Self, F>
Conditionally stops the Signal
.
For each value in self
it will call the test
function.
If test
returns true
then the Signal
will stop emitting
any future values.
The value which is passed to test
is always emitted no matter
what.
§Examples
// Stops the signal when x is above 5
let output = input.stop_if(|x| *x > 5);
§Performance
This is extremely efficient: it is guaranteed constant time, and it does not do any heap allocation.
fn debug(self) -> SignalDebug<Self>
Sourcefn broadcast(self) -> Broadcaster<Self>where
Self: Sized,
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 Signal
s.
See the documentation for Broadcaster
for more details.
Sourcefn poll_change_unpin(
&mut self,
cx: &mut Context<'_>,
) -> Poll<Option<Self::Item>>
fn poll_change_unpin( &mut self, cx: &mut Context<'_>, ) -> Poll<Option<Self::Item>>
A convenience for calling Signal::poll_change
on Unpin
types.