use dbuff::*;
use std::time::Duration;
#[derive(Debug, Clone)]
struct AppServices {
prefix: String,
multiplier: i32,
}
#[derive(Debug, Clone, Default)]
struct AppData {
greeting: String,
value: i32,
}
#[derive(Debug, Clone, wherror::Error)]
#[error(debug)]
struct CmdError;
struct Greet(String);
#[async_trait::async_trait]
impl Command<AppServices> for Greet {
type Output = String;
type Error = CmdError;
async fn execute(self, services: AppServices) -> Result<Self::Output, Self::Error> {
Ok(format!("{} {}", services.prefix, self.0))
}
}
struct Scale(i32);
#[async_trait::async_trait]
impl Command<AppServices> for Scale {
type Output = i32;
type Error = CmdError;
async fn execute(self, services: AppServices) -> Result<Self::Output, Self::Error> {
Ok(self.0 * services.multiplier)
}
}
#[tokio::main]
async fn main() {
let rt = tokio::runtime::Handle::current();
let services = AppServices {
prefix: ">>".into(),
multiplier: 3,
};
let (domain, write_handle) =
SharedDomainData::with_coalesce(AppData::default(), Duration::from_micros(500));
tokio::spawn(write_handle.run());
drop(domain.bind(services, rt.clone())
.exec(Greet("world".into()), |d, v: &String| d.greeting.clone_from(v))
.exec(Scale(10), |d, v: &i32| d.value = *v)
.go());
tokio::time::sleep(Duration::from_millis(10)).await;
let guard = domain.read();
assert_eq!(guard.greeting, ">> world");
assert_eq!(guard.value, 30);
println!("greeting = {}", guard.greeting);
println!("value = {}", guard.value);
}