use generic events struct instead of `StringEvents`

This new structure is generic over any type that implents `From`/`Into`
for the type specified.
This commit is contained in:
Matthew Nicholson 2019-03-30 22:31:56 -04:00
parent d63c2ef07b
commit 3edc4c3fa0
3 changed files with 11 additions and 46 deletions

View File

@ -262,7 +262,7 @@ impl Element {
let key = TokenTree::Ident(key.clone()); let key = TokenTree::Ident(key.clone());
let value = process_value(value); let value = process_value(value);
body.extend(quote!( body.extend(quote!(
element.events.#key = Some(typed_html::events::IntoEventHandler::into_event_handler(#value)); element.events.#key = Some(#value.into());
)); ));
} }

View File

@ -29,52 +29,17 @@ pub trait IntoEventHandler<T: OutputType, E> {
fn into_event_handler(self) -> Box<dyn EventHandler<T, E>>; fn into_event_handler(self) -> Box<dyn EventHandler<T, E>>;
} }
/// An uninhabited event type for string handlers. macro_rules! declare_events_struct {
pub enum StringEvent {}
impl EventHandler<String, StringEvent> for &'static str {
fn attach(&mut self, _target: &mut <String as OutputType>::EventTarget) {
panic!("Silly wabbit, strings as event handlers are only for printing.");
}
fn render(&self) -> Option<String> {
Some(self.to_string())
}
}
impl IntoEventHandler<String, StringEvent> for &'static str {
fn into_event_handler(self) -> Box<dyn EventHandler<String, StringEvent>> {
Box::new(self)
}
}
impl EventHandler<String, StringEvent> for String {
fn attach(&mut self, _target: &mut <String as OutputType>::EventTarget) {
panic!("Silly wabbit, strings as event handlers are only for printing.");
}
fn render(&self) -> Option<String> {
Some(self.clone())
}
}
impl IntoEventHandler<String, StringEvent> for String {
fn into_event_handler(self) -> Box<dyn EventHandler<String, StringEvent>> {
Box::new(self)
}
}
macro_rules! declare_string_events {
($($name:ident,)*) => { ($($name:ident,)*) => {
pub struct StringEvents { pub struct Events<T> {
$( $(
pub $name: Option<Box<dyn EventHandler<String, StringEvent>>>, pub $name: Option<T>,
)* )*
} }
impl Default for StringEvents { impl<T> Default for Events<T> {
fn default() -> Self { fn default() -> Self {
StringEvents { Events {
$( $(
$name: None, $name: None,
)* )*
@ -82,12 +47,12 @@ macro_rules! declare_string_events {
} }
} }
impl Display for StringEvents { impl<T: Display> Display for Events<T> {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
$( $(
if let Some(ref value) = self.$name { if let Some(ref value) = self.$name {
write!(f, " on{}=\"{}\"", stringify!($name), let attribute = encode_attribute(&value.to_string());
encode_attribute(value.render().unwrap().as_str()))?; write!(f, " on{}=\"{}\"", stringify!($name), attribute)?;
} }
)* )*
Ok(()) Ok(())
@ -96,7 +61,7 @@ macro_rules! declare_string_events {
} }
} }
declare_string_events! { declare_events_struct! {
abort, abort,
autocomplete, autocomplete,
autocompleteerror, autocompleteerror,

View File

@ -221,7 +221,7 @@ pub trait OutputType {
/// String output /// String output
impl OutputType for String { impl OutputType for String {
type Events = events::StringEvents; type Events = events::Events<String>;
type EventTarget = (); type EventTarget = ();
type EventListenerHandle = (); type EventListenerHandle = ();
} }