use std::sync::mpsc::Sender;
use std::sync::{Arc, Mutex};
use anyhow::Result;
use arora_bridge::FakeBridge;
use arora_hal::{Hal, HalDescription, HalResult};
use arora_simple_data_store::SimpleDataStore;
use arora_types::data::{Key, State, StateChange, Subscription};
use arora_types::value::Value;
use async_trait::async_trait;
#[derive(Default)]
struct ExampleHal {
inner: Arc<Mutex<Inner>>,
}
#[derive(Default)]
struct Inner {
state: State,
subscribers: Vec<Sender<StateChange>>,
}
#[async_trait]
impl Hal for ExampleHal {
async fn describe(&self) -> HalDescription {
HalDescription {
model_family: Some("example-device".to_string()),
hardware_version: Some("0.1".to_string()),
software_version: Some(env!("CARGO_PKG_VERSION").to_string()),
}
}
async fn read(&self, keys: &[Key]) -> HalResult<Vec<Option<Value>>> {
let inner = self.inner.lock().unwrap();
Ok(keys
.iter()
.map(|key| inner.state.get(key).cloned().flatten())
.collect())
}
async fn read_all(&self) -> HalResult<State> {
Ok(self.inner.lock().unwrap().state.clone())
}
async fn write(&self, changes: StateChange) -> HalResult<()> {
if changes.is_empty() {
return Ok(());
}
let mut inner = self.inner.lock().unwrap();
inner.state.apply(changes.clone());
inner
.subscribers
.retain(|tx| tx.send(changes.clone()).is_ok());
Ok(())
}
fn updates(&self) -> Subscription {
let (tx, rx) = std::sync::mpsc::channel();
self.inner.lock().unwrap().subscribers.push(tx);
Subscription::new(rx)
}
}
fn main() -> Result<()> {
arora::launch(
Arc::new(ExampleHal::default()),
Arc::new(FakeBridge::new()),
SimpleDataStore::new(),
)
}