xilem_html: Add more text views (support numbers directly as view) (#154)

This commit is contained in:
Philipp Mildenberger 2023-11-28 14:29:52 +01:00 committed by GitHub
parent 5b3de313c7
commit f643dc491b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 90 additions and 103 deletions

View File

@ -93,119 +93,106 @@ xilem_core::generate_adapt_state_view! {View, Cx, ChangeFlags;}
// strings -> text nodes // strings -> text nodes
impl ViewMarker for &'static str {} macro_rules! impl_string_view {
impl<T, A> View<T, A> for &'static str { ($ty:ty) => {
type State = (); impl ViewMarker for $ty {}
type Element = web_sys::Text; impl<T, A> View<T, A> for $ty {
type State = ();
type Element = web_sys::Text;
fn build(&self, _cx: &mut Cx) -> (Id, Self::State, Self::Element) { fn build(&self, _cx: &mut Cx) -> (Id, Self::State, Self::Element) {
let el = new_text(self); (Id::next(), (), new_text(self))
let id = Id::next(); }
(id, (), el)
}
fn rebuild( fn rebuild(
&self, &self,
_cx: &mut Cx, _cx: &mut Cx,
prev: &Self, prev: &Self,
_id: &mut Id, _id: &mut Id,
_state: &mut Self::State, _state: &mut Self::State,
element: &mut Self::Element, element: &mut Self::Element,
) -> ChangeFlags { ) -> ChangeFlags {
let mut is_changed = ChangeFlags::empty(); if prev != self {
if prev != self { element.set_data(self);
element.set_data(self); ChangeFlags::OTHER_CHANGE
is_changed |= ChangeFlags::OTHER_CHANGE; } else {
ChangeFlags::empty()
}
}
fn message(
&self,
_id_path: &[Id],
_state: &mut Self::State,
message: Box<dyn std::any::Any>,
_app_state: &mut T,
) -> MessageResult<A> {
MessageResult::Stale(message)
}
} }
is_changed };
}
fn message(
&self,
_id_path: &[Id],
_state: &mut Self::State,
_message: Box<dyn std::any::Any>,
_app_state: &mut T,
) -> MessageResult<A> {
MessageResult::Nop
}
} }
impl ViewMarker for String {} impl_string_view!(String);
impl<T, A> View<T, A> for String { impl_string_view!(&'static str);
type State = (); impl_string_view!(Cow<'static, str>);
type Element = web_sys::Text;
fn build(&self, _cx: &mut Cx) -> (Id, Self::State, Self::Element) { // Specialization would probably avoid manual implementation,
let el = new_text(self); // but it's probably a good idea to have more control than via a blanket impl
let id = Id::next(); macro_rules! impl_to_string_view {
(id, (), el) ($ty:ty) => {
} impl ViewMarker for $ty {}
impl<T, A> View<T, A> for $ty {
type State = ();
type Element = web_sys::Text;
fn rebuild( fn build(&self, _cx: &mut Cx) -> (Id, Self::State, Self::Element) {
&self, (Id::next(), (), new_text(&self.to_string()))
_cx: &mut Cx, }
prev: &Self,
_id: &mut Id, fn rebuild(
_state: &mut Self::State, &self,
element: &mut Self::Element, _cx: &mut Cx,
) -> ChangeFlags { prev: &Self,
let mut is_changed = ChangeFlags::empty(); _id: &mut Id,
if prev != self { _state: &mut Self::State,
element.set_data(self); element: &mut Self::Element,
is_changed |= ChangeFlags::OTHER_CHANGE; ) -> ChangeFlags {
if prev != self {
element.set_data(&self.to_string());
ChangeFlags::OTHER_CHANGE
} else {
ChangeFlags::empty()
}
}
fn message(
&self,
_id_path: &[Id],
_state: &mut Self::State,
message: Box<dyn std::any::Any>,
_app_state: &mut T,
) -> MessageResult<A> {
MessageResult::Stale(message)
}
} }
is_changed };
}
fn message(
&self,
_id_path: &[Id],
_state: &mut Self::State,
_message: Box<dyn std::any::Any>,
_app_state: &mut T,
) -> MessageResult<A> {
MessageResult::Nop
}
} }
impl ViewMarker for Cow<'static, str> {} // Allow numbers to be used directly as a view
impl<T, A> View<T, A> for Cow<'static, str> { impl_to_string_view!(f32);
type State = (); impl_to_string_view!(f64);
type Element = web_sys::Text; impl_to_string_view!(i8);
impl_to_string_view!(u8);
fn build(&self, _cx: &mut Cx) -> (Id, Self::State, Self::Element) { impl_to_string_view!(i16);
let el = new_text(self); impl_to_string_view!(u16);
let id = Id::next(); impl_to_string_view!(i32);
(id, (), el) impl_to_string_view!(u32);
} impl_to_string_view!(i64);
impl_to_string_view!(u64);
fn rebuild( impl_to_string_view!(u128);
&self, impl_to_string_view!(isize);
_cx: &mut Cx, impl_to_string_view!(usize);
prev: &Self,
_id: &mut Id,
_state: &mut Self::State,
element: &mut Self::Element,
) -> ChangeFlags {
let mut is_changed = ChangeFlags::empty();
if prev != self {
element.set_data(self);
is_changed |= ChangeFlags::OTHER_CHANGE;
}
is_changed
}
fn message(
&self,
_id_path: &[Id],
_state: &mut Self::State,
_message: Box<dyn std::any::Any>,
_app_state: &mut T,
) -> MessageResult<A> {
MessageResult::Nop
}
}
fn new_text(text: &str) -> web_sys::Text { fn new_text(text: &str) -> web_sys::Text {
web_sys::Text::new_with_data(text).unwrap() web_sys::Text::new_with_data(text).unwrap()