use std::fmt;
use std::mem;
use wasm_bindgen::prelude::*;
pub use crate::component::Component;
pub use crate::app::Dispatcher;
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum EventHandler<'a, Message> {
Msg(&'a Message),
Fn(fn(web_sys::Event) -> Option<Message>),
FnMsg(&'a Message, fn(Message, web_sys::Event) -> Option<Message>),
InputValue(fn(String) -> Option<Message>),
InputEvent(fn(web_sys::InputEvent) -> Option<Message>),
}
pub enum WebItem<Message> {
Element(web_sys::Element),
Text(web_sys::Text),
Closure(Closure<dyn FnMut(web_sys::Event)>),
Component(Box<dyn Component<Message>>),
Taken,
Up,
}
impl<Message> WebItem<Message> {
pub fn take(&mut self) -> Self {
let mut taken = WebItem::Taken;
mem::swap(self, &mut taken);
taken
}
pub fn as_element(&self) -> Option<&web_sys::Element> {
match self {
WebItem::Element(node) => Some(node),
_ => None,
}
}
pub fn as_text(&self) -> Option<&web_sys::Text> {
match self {
WebItem::Text(node) => Some(node),
_ => None,
}
}
pub fn as_closure(&self) -> Option<&Closure<dyn FnMut(web_sys::Event)>> {
match self {
WebItem::Closure(closure) => Some(closure),
_ => None,
}
}
pub fn as_component(&self) -> Option<&Box<dyn Component<Message>>> {
match self {
WebItem::Component(c) => Some(c),
_ => None,
}
}
}
impl<Message> fmt::Debug for WebItem<Message> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
WebItem::Element(node) => write!(f, "Element({:?})", node),
WebItem::Text(text) => write!(f, "Text({:?})", text),
WebItem::Closure(_) => write!(f, "Closure(_)"),
WebItem::Component(_) => write!(f, "Component(_)"),
WebItem::Taken => write!(f, "Taken"),
WebItem::Up => write!(f, "Up"),
}
}
}
pub type Storage<Message> = Vec<WebItem<Message>>;
#[derive(Debug, PartialEq)]
pub enum DomItem<'a, Message, Command, K> {
Element {
name: &'a str,
key: Option<&'a K>,
},
Text(&'a str),
UnsafeInnerHtml(&'a str),
Attr {
name: &'a str,
value: &'a str,
},
Event {
trigger: &'a str,
handler: EventHandler<'a, Message>,
},
Up,
Component {
key: Option<&'a K>,
msg: Message,
create: fn(Dispatcher<Message, Command>) -> Box<dyn Component<Message>>,
},
Key(&'a K),
}
pub trait DomIter<Message: Clone, Command, K> {
fn dom_iter<'a>(&'a self) -> Box<dyn Iterator<Item = DomItem<'a, Message, Command, K>> + 'a>;
}