[−][src]Struct froop::Imitator
Imitators are used to create cyclic streams. Created by
Stream::imitator()
.
Anatomy of an FRP app
cycle.js taught me one one way to structure an app built on FRP. A key ingredient are "cyclic streams".
- A driver is something isolating communcation to the rest of thew world. This could be requests against an API, database or a UI.
- Drivers are two-way communications.
- An app is a main function that have driver input as argument and driver output as return value.
- App input is called sources.
- App output is called sinks.
These components would be in different files, but here's a distilled example:
use froop::{Stream, Sink}; enum DriverIn { // ... event type of input _from_ the driver. } #[derive(Clone)] // needed for imitate enum DriverOut { // ... event type of output _to_ the driver. } // The driver, which also is a function. fn my_driver(out: Stream<DriverOut>) -> Stream<DriverIn> { let sink = Stream::sink(); // React to input from `out` and // produce output into `sink`. sink.stream() } // Input to the app_main from the drivers struct AppSources { my_driver: Stream<DriverIn>, } // Output from the app_main to the drivers struct AppSinks { my_driver: Stream<DriverOut>, } // The main function of the app fn app_main(sources: AppSources) -> AppSinks { // React to input from the sources, and derive // output to the sinks. Produce an "app state". // This is just to make it compile. The output // would be derived from the app state. let my_driver_out = Stream::never(); return AppSinks { my_driver: my_driver_out, } } // This function does what "cycle.js run" does (but in // javascript it can be dynamic). fn run() { // imitator to cycle back output from main let driver_out = Stream::imitator(); // connect driver let driver_in = my_driver(driver_out.stream()); // create sources for app main function let app_sources = AppSources { my_driver: driver_in, }; // run main function let app_sinks = app_main(app_sources); // cycle back output to driver driver_out.imitate(&app_sinks.my_driver); }
Methods
impl<T: Clone> Imitator<T>
[src]
pub fn imitate(self, other: &Stream<T>) -> Subscription
[src]
Start imitating another stream. This consumes the imitator since it can only imitate one other stream.
pub fn stream(&self) -> Stream<T>
[src]
Get a stream of events from this imitator. One stream instance is created for each call, and they all receive the events from the imitated stream.
let imitator = froop::Stream::imitator(); let coll1 = imitator.stream().collect(); let coll2 = imitator.stream().collect(); let sink = froop::Stream::sink(); let stream = sink.stream(); imitator.imitate(&stream); sink.update(42); sink.end(); // imitator also ends here assert_eq!(coll1.wait(), vec![42]); assert_eq!(coll2.wait(), vec![42]);
Auto Trait Implementations
Blanket Implementations
impl<T> From for T
[src]
impl<T, U> Into for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = !
🔬 This is a nightly-only experimental API. (
try_from
)The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T> Borrow for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> BorrowMut for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T, U> TryInto for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,