use crate::{App, Core, EffectFFI, Request, Resolvable, ResolveError, bridge::BridgeError};
mod bridge;
mod effect_conversion;
mod effect_handling;
pub use crate::bridge::{BincodeFfiFormat, FfiFormat, JsonFfiFormat};
pub use bridge::Bridge;
pub use effect_conversion::MapEffectLayer;
pub use effect_handling::{EffectMiddleware, EffectResolver, HandleEffectLayer};
use serde::Deserialize;
pub trait Layer: Send + Sync + Sized {
type Event;
type Effect;
type ViewModel;
fn update<F>(&self, event: Self::Event, effect_callback: F) -> Vec<Self::Effect>
where
F: Fn(Vec<Self::Effect>) + Sync + Send + 'static;
fn resolve<Output, F>(
&self,
request: &mut impl Resolvable<Output>,
output: Output,
effect_callback: F,
) -> Result<Vec<Self::Effect>, ResolveError>
where
F: Fn(Vec<Self::Effect>) + Sync + Send + 'static;
fn process_tasks<F>(&self, effect_callback: F) -> Vec<Self::Effect>
where
F: Fn(Vec<Self::Effect>) + Sync + Send + 'static;
fn view(&self) -> Self::ViewModel;
fn handle_effects_using<EM>(self, middleware: EM) -> HandleEffectLayer<Self, EM>
where
EM: EffectMiddleware + 'static,
Self::Effect: TryInto<Request<EM::Op>, Error = Self::Effect>,
{
HandleEffectLayer::new(self, middleware)
}
fn map_effect<NewEffect>(self) -> MapEffectLayer<Self, NewEffect>
where
NewEffect: From<Self::Effect> + Send + 'static,
{
MapEffectLayer::new(self)
}
fn bridge<Format: FfiFormat>(
self,
effect_callback: impl Fn(Result<Vec<u8>, BridgeError<Format>>) + Send + Sync + 'static,
) -> Bridge<Self, Format>
where
Self::Effect: EffectFFI,
Self::Event: for<'a> Deserialize<'a>,
{
Bridge::new(self, effect_callback)
}
}
impl<A: App> Layer for Core<A>
where
A: Send + Sync + 'static,
A::Model: Send + Sync + 'static,
{
type Event = A::Event;
type Effect = A::Effect;
type ViewModel = A::ViewModel;
fn update<F: Fn(Vec<Self::Effect>) + Send + Sync + 'static>(
&self,
event: Self::Event,
_effect_callback: F,
) -> Vec<Self::Effect> {
self.process_event(event)
}
fn resolve<Output, F: Fn(Vec<Self::Effect>) + Send + Sync + 'static>(
&self,
request: &mut impl Resolvable<Output>,
output: Output,
_effect_callback: F,
) -> Result<Vec<Self::Effect>, ResolveError> {
self.resolve(request, output)
}
fn view(&self) -> Self::ViewModel {
self.view()
}
fn process_tasks<F>(&self, _effect_callback: F) -> Vec<Self::Effect>
where
F: Fn(Vec<Self::Effect>) + Sync + Send + 'static,
{
self.process()
}
}