use std::future::Future;
use std::pin::Pin;
use vantage_core::Result;
use crate::dio::Dio;
use crate::ops::{ChangeEvent, QueryDescriptor, WriteOp};
pub type DioCallbackFuture<'a> = Pin<Box<dyn Future<Output = Result<()>> + Send + 'a>>;
pub type DioCallback =
Box<dyn for<'a> Fn(&'a Dio) -> DioCallbackFuture<'a> + Send + Sync + 'static>;
pub type DioWriteCallback =
Box<dyn for<'a> Fn(&'a Dio, WriteOp) -> DioCallbackFuture<'a> + Send + Sync + 'static>;
pub type DioEventCallback =
Box<dyn for<'a> Fn(&'a Dio, ChangeEvent) -> DioCallbackFuture<'a> + Send + Sync + 'static>;
pub type DioQueryCallback =
Box<dyn for<'a> Fn(&'a Dio, QueryDescriptor) -> DioCallbackFuture<'a> + Send + Sync + 'static>;
#[derive(Default)]
pub struct LensCallbacks {
pub on_start: Option<DioCallback>,
pub on_refresh: Option<DioCallback>,
pub on_write: Option<DioWriteCallback>,
pub on_event: Option<DioEventCallback>,
pub on_query: Option<DioQueryCallback>,
}
pub fn boxed_dio_callback<F, Fut>(f: F) -> DioCallback
where
F: for<'a> Fn(&'a Dio) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Result<()>> + Send + 'static,
{
Box::new(move |dio| Box::pin(f(dio)))
}
pub fn boxed_dio_write_callback<F, Fut>(f: F) -> DioWriteCallback
where
F: for<'a> Fn(&'a Dio, WriteOp) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Result<()>> + Send + 'static,
{
Box::new(move |dio, op| Box::pin(f(dio, op)))
}
pub fn boxed_dio_event_callback<F, Fut>(f: F) -> DioEventCallback
where
F: for<'a> Fn(&'a Dio, ChangeEvent) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Result<()>> + Send + 'static,
{
Box::new(move |dio, ev| Box::pin(f(dio, ev)))
}
pub fn boxed_dio_query_callback<F, Fut>(f: F) -> DioQueryCallback
where
F: for<'a> Fn(&'a Dio, QueryDescriptor) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Result<()>> + Send + 'static,
{
Box::new(move |dio, q| Box::pin(f(dio, q)))
}