use observable_property_tokio::ObservableProperty;
use std::sync::Arc;
#[derive(Clone, Debug)]
struct User {
id: u64,
name: String,
email: String,
active: bool,
login_count: u32,
}
#[tokio::main]
async fn main() -> Result<(), observable_property_tokio::PropertyError> {
println!("=== Complex Data Type Example ===");
println!("This example demonstrates using ObservableProperty with complex data types");
let initial_user = User {
id: 1,
name: "Alice".to_string(),
email: "alice@example.com".to_string(),
active: true,
login_count: 0,
};
let user_property = ObservableProperty::new(initial_user);
println!("\nInitial user:");
println!("{:#?}", user_property.get()?);
let _subscription = user_property.subscribe_with_token(Arc::new(|old_user, new_user| {
println!("\nUser changed:");
println!("Name: {} -> {}", old_user.name, new_user.name);
println!("Email: {} -> {}", old_user.email, new_user.email);
println!("Active: {} -> {}", old_user.active, new_user.active);
println!("Login count: {} -> {}", old_user.login_count, new_user.login_count);
}))?;
let _name_change_subscription = user_property.subscribe_filtered_with_token(
Arc::new(|_, new_user| {
println!("\n[NAME CHANGE ALERT] User name is now: {}", new_user.name);
}),
|old_user, new_user| old_user.name != new_user.name
)?;
let _status_change_subscription = user_property.subscribe_filtered_with_token(
Arc::new(|_, new_user| {
if new_user.active {
println!("\n[STATUS ALERT] User is now active");
} else {
println!("\n[STATUS ALERT] User is now inactive");
}
}),
|old_user, new_user| old_user.active != new_user.active
)?;
println!("\nUpdating user...");
user_property.update(|mut user| {
user.name = "Alice Smith".to_string();
user.login_count += 1;
user
})?;
println!("\nUpdating email only...");
user_property.update(|mut user| {
user.email = "alice.smith@example.com".to_string();
user
})?;
println!("\nDeactivating user...");
user_property.update(|mut user| {
user.active = false;
user
})?;
println!("\nFinal user state:");
println!("{:#?}", user_property.get()?);
Ok(())
}