use std::any::Any;
use std::sync::Arc;
use tauri::ipc::{Channel as TauriChannel, JavaScriptChannelId};
use tauri::{State, StateManager};
type ChannelFactory<'a> = dyn Fn(JavaScriptChannelId) -> TauriChannel + Send + Sync + 'a;
#[doc(hidden)]
pub struct Context<'a> {
values: &'a [&'a (dyn Any + Send + Sync)],
state: Option<Arc<StateManager>>,
channels: Option<&'a ChannelFactory<'a>>,
}
impl<'a> Context<'a> {
pub fn new(values: &'a [&'a (dyn Any + Send + Sync)]) -> Self {
Self {
values,
state: None,
channels: None,
}
}
pub fn empty() -> Context<'static> {
Context {
values: &[],
state: None,
channels: None,
}
}
pub fn with_state(mut self, state: Arc<StateManager>) -> Self {
self.state = Some(state);
self
}
pub fn with_channels(mut self, channels: &'a ChannelFactory<'a>) -> Self {
self.channels = Some(channels);
self
}
pub fn extract<T: Clone + 'static>(&self) -> Option<T> {
self.values
.iter()
.find_map(|value| value.downcast_ref::<T>())
.cloned()
}
pub fn state<T: Send + Sync + 'static>(&self) -> Option<State<'_, T>> {
self.state.as_deref().and_then(|state| state.try_get::<T>())
}
pub fn state_manager(&self) -> Option<Arc<StateManager>> {
self.state.clone()
}
pub fn channel<T>(&self, id: JavaScriptChannelId) -> Option<crate::Channel<T>> {
self.channels
.map(|make| crate::Channel::from_tauri(make(id)))
}
}