//! Tests some rather "advanced" API usages for the [reactive_mutiny] library that //! that are too complicated or simply don't have enough didactics to be part of the "examples" set. //! //! NOTE: many "tests" here have no real assertions, as they are used only to verify the API is able to represent certain models use std::fmt::Debug; use std::sync::Arc; use std::time::Duration; use futures::StreamExt; use reactive_mutiny::prelude::advanced::{ GenericUni, UniZeroCopyAtomic, Instruments, }; #[ctor::ctor] fn suite_setup() { simple_logger::SimpleLogger::new().with_utc_timestamps().init().unwrap_or_else(|_| eprintln!("--> LOGGER WAS ALREADY STARTED")); } /// Checks that our channels (for [Uni]s or [Multi]s) may be used in elaborated generics expansions.\ /// Observe here that the `pipeline_builder` function, in order to keep a simple signature, shouldn't be passed down the calling chain: /// instead, a [Uni]/[Multi] must be created on the first level, or else the code won't compile (as Rust wouldn't be able to resolve the intricate generic typings resulting from that) #[cfg_attr(not(doc), tokio::test)] async fn elaborated_generics_on_call_chains() { // generics typing const INSTRUMENTS: usize = Instruments::LogsWithExpensiveMetrics.into(); const BUFFER_SIZE: usize = 1024; type Uni = UniZeroCopyAtomic; // type Uni = UniMoveAtomic; #[allow(dead_code)] trait CustomTrait { fn get_data(self) -> T; } #[derive(Debug)] #[allow(dead_code)] struct CustomType {data: T} impl CustomTrait> for CustomType { fn get_data(self) -> CustomType { CustomType {data: self.data} } } async fn with_generics + Send + Sync + Debug> (events_sender: Arc>, value: RemoteMessages) -> bool { assert!(events_sender.send_with(|slot| *slot = value).is_ok(), "couldn't send value"); events_sender.close(Duration::from_millis(100)).await } // notice the simple `pipeline_builder`, that is able to make it down the chain of `with_generics()` call only in the `Uni` / `Multi` form // (as opposed to passing the `pipeline_builder` as a parameter to `with_generics()`, which would, then, create the `Uni` / `Multi` there) let uni = Uni::>::new("advanced generics") .spawn_non_futures_non_fallibles_executors(1, |remote_messages_stream| remote_messages_stream.map(|_in_msg| CustomType {data: true}), |_executor| async {}); with_generics(uni, CustomType {data: false}).await; }