use observable_property::ObservableProperty;
use std::sync::Arc;
use std::time::Duration;
use std::pin::Pin;
use std::task::{Context, Poll, Wake, Waker};
use std::future::Future;
#[cfg(not(feature = "async"))]
fn main() {
println!("This example requires the 'async' feature to be enabled.");
println!("Run with: cargo run --example async_stream --features async");
}
#[cfg(feature = "async")]
fn main() {
println!("=== Observable Property Async Stream Example (std-only) ===\n");
println!("Example 1: Waiting for specific condition");
println!("------------------------------------------");
let counter = Arc::new(ObservableProperty::new(0));
let counter_clone = counter.clone();
let handle = std::thread::spawn(move || {
for i in 1..=10 {
std::thread::sleep(Duration::from_millis(100));
counter_clone.set(i).ok();
println!(" Counter set to: {}", i);
}
});
let future = counter.wait_for(|value| *value >= 5);
let result = block_on(future);
println!(" ✓ Counter reached: {}\n", result);
handle.join().expect("Thread panicked");
println!("Example 2: Temperature threshold monitoring");
println!("-------------------------------------------");
let temperature = Arc::new(ObservableProperty::new(20.0));
let temp_clone = temperature.clone();
let handle2 = std::thread::spawn(move || {
for i in 0..15 {
std::thread::sleep(Duration::from_millis(50));
let new_temp = 20.0 + i as f64 * 0.8;
temp_clone.set(new_temp).ok();
}
});
println!(" Waiting for temperature > 28°C...");
let future = temperature.wait_for(|temp| *temp > 28.0);
let critical = block_on(future);
println!(" ✓ Critical temperature reached: {:.1}°C\n", critical);
handle2.join().expect("Thread panicked");
println!("Example 3: Waiting for ready status");
println!("------------------------------------");
let status = Arc::new(ObservableProperty::new("initializing".to_string()));
let status_clone = status.clone();
let handle3 = std::thread::spawn(move || {
let states = vec!["loading", "processing", "validating", "ready"];
for state in states {
std::thread::sleep(Duration::from_millis(200));
println!(" Status: {}", state);
status_clone.set(state.to_string()).ok();
}
});
println!(" Waiting for 'ready' status...");
let future = status.wait_for(|s| s == "ready");
let ready_status = block_on(future);
println!(" ✓ Status achieved: {}\n", ready_status);
handle3.join().expect("Thread panicked");
println!("=== All Examples Completed Successfully ===\n");
println!("Note: This implementation uses only std library primitives.");
println!("For a full async ecosystem experience, consider using futures-rs or tokio.");
}
#[cfg(feature = "async")]
fn block_on<F: Future>(mut future: F) -> F::Output {
use std::sync::Arc;
use std::thread;
let mut future = unsafe { Pin::new_unchecked(&mut future) };
struct DummyWaker;
impl Wake for DummyWaker {
fn wake(self: Arc<Self>) {}
}
let waker = Waker::from(Arc::new(DummyWaker));
let mut context = Context::from_waker(&waker);
loop {
match future.as_mut().poll(&mut context) {
Poll::Ready(output) => return output,
Poll::Pending => {
thread::sleep(Duration::from_millis(10));
}
}
}
}