#![allow(dead_code)]
use anyhow::Error;
use async_injector::{Key, Provider};
use std::sync::Arc;
#[derive(Debug)]
struct Database;
#[derive(Clone, Debug)]
struct Thing {
title: String,
db: Arc<Database>,
}
#[derive(Provider)]
struct ThingProvider {
#[dependency(tag = "\"title\"")]
title: String,
#[dependency]
db: Arc<Database>,
}
#[tokio::main]
async fn main() -> Result<(), Error> {
use std::{thread, time::Duration};
let injector = async_injector::Injector::new();
let thread_injector = injector.clone();
let title_key = Key::<String>::tagged("title")?;
let t = tokio::spawn(async move {
let injector = thread_injector;
thread::sleep(Duration::from_secs(1));
injector
.update_key(&title_key, String::from("New Title"))
.await;
thread::sleep(Duration::from_secs(1));
injector.update(Arc::new(Database)).await;
thread::sleep(Duration::from_secs(1));
injector.clear_key(&title_key).await;
thread::sleep(Duration::from_secs(1));
injector
.update_key(&title_key, String::from("Bye Bye"))
.await;
});
let thing_var = injector.var::<Thing>().await;
let t2 = tokio::spawn(async move {
loop {
tokio::time::sleep(Duration::from_secs(1)).await;
let thing = thing_var.read().await;
println!("Synchronized thing: {:?}", thing.as_deref());
if let Some(thing) = thing.as_deref() {
if thing.title == "Bye Bye" {
break;
}
}
}
});
let mut provider = ThingProvider::provider(&injector).await?;
let task = async {
let (mut thing_stream, thing) = injector.stream::<Thing>().await;
println!("First thing: {:?}", thing);
loop {
let thing = thing_stream.recv().await;
println!("New thing: {:?}", thing);
if let Some(thing) = thing {
if thing.title == "Bye Bye" {
break;
}
}
}
};
tokio::pin!(task);
tokio::select! {
_ = task => {},
update = provider.update() => {
match update {
Some(update) => {
injector.update(Thing {
title: update.title,
db: update.db,
}).await;
}
None => {
injector.clear::<Thing>().await;
}
}
},
}
let _ = t.await.expect("thread didn't exit gracefully");
let _ = t2.await.expect("thread didn't exit gracefully");
Ok(())
}