#![allow(dead_code, unused_variables)]
use rust_pattern_macros::observable;
use rust_patterns::{Observable, Observer, ObserverRegistry};
use std::sync::Arc;
#[observable(state = u64, error = String)]
struct Counter {
value: u64,
}
impl Counter {
#[allow(dead_code)]
pub fn with_value(value: u64) -> Self {
Self {
value,
registry: ObserverRegistry::new(),
}
}
pub fn increment(&mut self) {
self.value += 1;
let _ = self.notify(&self.value);
}
}
#[allow(dead_code)]
struct Logger {
log_level: u8,
}
#[derive(Debug)]
#[allow(dead_code)]
enum SensorError {
InvalidReading,
CommunicationFailed,
}
impl std::fmt::Display for SensorError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
SensorError::InvalidReading => write!(f, "Invalid sensor reading"),
SensorError::CommunicationFailed => write!(f, "Sensor communication failed"),
}
}
}
impl std::error::Error for SensorError {}
#[observable(state = f64, error = SensorError)]
struct TemperatureSensor {
temperature: f64,
}
struct CounterDisplay;
impl Observer for CounterDisplay {
type Subject = Counter;
fn update(&self, state: &u64) -> Result<(), String> {
println!("Counter updated: {}", state);
Ok(())
}
}
#[allow(dead_code)]
struct TemperatureDisplay;
struct TemperatureObserver;
impl Observer for TemperatureObserver {
type Subject = TemperatureSensor;
fn update(&self, state: &f64) -> Result<(), SensorError> {
println!("Temperature: {:.1}°C", state);
Ok(())
}
}
fn main() {
let mut counter = Counter {
value: 0,
registry: rust_patterns::ObserverRegistry::new(),
};
let display = Arc::new(CounterDisplay);
counter.attach(display.clone());
counter.increment(); counter.increment();
let mut sensor = TemperatureSensor {
temperature: 20.0,
registry: ObserverRegistry::new(),
};
let temp_display = Arc::new(TemperatureObserver);
sensor.attach(temp_display.clone());
sensor.temperature = 25.5;
let _ = sensor.notify(&sensor.temperature);
sensor.temperature = 30.0;
sensor.notify_ignore_error(&sensor.temperature);
println!("All examples completed successfully!");
}