#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(feature = "gen_blocks", feature(async_iterator, gen_blocks))]
#![warn(missing_docs)]
use smallvec::SmallVec;
#[allow(async_fn_in_trait)]
pub trait Component: Sized {
type Init<'a>;
type Message;
type Event;
type Error: std::fmt::Debug;
async fn init(
init: Self::Init<'_>,
sender: &ComponentSender<Self>,
) -> Result<Self, Self::Error>;
async fn start(&mut self, sender: &ComponentSender<Self>) -> ! {
let _ = sender;
std::future::pending().await
}
async fn update(
&mut self,
message: Self::Message,
sender: &ComponentSender<Self>,
) -> Result<bool, Self::Error> {
let _ = message;
let _ = sender;
Ok(false)
}
fn render(&mut self, sender: &ComponentSender<Self>) -> Result<(), Self::Error> {
let _ = sender;
Ok(())
}
async fn update_children(&mut self) -> Result<bool, Self::Error> {
Ok(false)
}
fn render_children(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}
#[derive(Debug)]
pub(crate) enum ComponentMessage<M, E> {
Message(M),
Event(E),
}
#[derive(Debug)]
#[repr(transparent)]
pub struct ComponentSender<T: Component>(Channel<ComponentMessage<T::Message, T::Event>>);
impl<T: Component> ComponentSender<T> {
pub(crate) fn new() -> Self {
Self(Channel::new())
}
pub(crate) fn from_ref(c: &Channel<ComponentMessage<T::Message, T::Event>>) -> &Self {
unsafe { std::mem::transmute(c) }
}
pub fn post(&self, message: T::Message) {
self.0.send(ComponentMessage::Message(message))
}
pub fn output(&self, event: T::Event) {
self.0.send(ComponentMessage::Event(event))
}
pub(crate) async fn wait(&self) {
self.0.wait().await
}
pub(crate) fn fetch_all(&self) -> SmallVec<[ComponentMessage<T::Message, T::Event>; 1]> {
self.0.fetch_all()
}
pub fn cast<U: Component<Message = T::Message, Event = T::Event>>(
&self,
) -> &ComponentSender<U> {
ComponentSender::from_ref(&self.0)
}
}
impl<T: Component> Clone for ComponentSender<T> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
mod channel;
use channel::*;
mod child;
pub use child::*;
mod collection;
pub use collection::*;
mod macros;
pub use macros::*;
mod run;
pub use run::*;
mod boxed;
pub use boxed::*;
#[cfg(feature = "gen_blocks")]
mod stream;