Skip to content

Commit

Permalink
Create OneOf view and refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
matthunz committed Jan 8, 2024
1 parent 60a7310 commit f238868
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 9 deletions.
95 changes: 95 additions & 0 deletions src/view/mod.rs
@@ -1,4 +1,5 @@
use crate::Context;
use std::mem;
use std::{marker::PhantomData, sync::Arc};

mod from_fn;
Expand Down Expand Up @@ -76,6 +77,100 @@ impl<T, M, V: View<T, M>> View<T, M> for Option<V> {
}
}

pub struct OneOf<A, B> {
data: Option<OneOfData<A, B>>,
}

impl<A, B> OneOf<A, B> {
pub fn a(value: A) -> Self {
Self {
data: Some(OneOfData::A(value)),
}
}

pub fn b(value: B) -> Self {
Self {
data: Some(OneOfData::B(value)),
}
}

pub fn data(&self) -> &OneOfData<A, B> {
self.data.as_ref().unwrap()
}
}

pub enum OneOfData<A, B> {
A(A),
B(B),
}

impl<ViewT, ViewM, A, B> View<ViewT, ViewM> for OneOf<A, B>
where
A: View<ViewT, ViewM>,
B: View<ViewT, ViewM>,
{
type Element = OneOfData<(A, A::Element), (B, B::Element)>;

fn build(&mut self, cx: &mut Context<ViewM>, state: &mut ViewT) -> Self::Element {
match self.data.take().unwrap() {
OneOfData::A(mut view) => {
let elem = view.build(cx, state);
OneOfData::A((view, elem))
}
OneOfData::B(mut view) => {
let elem = view.build(cx, state);
OneOfData::B((view, elem))
}
}
}

fn rebuild(&mut self, cx: &mut Context<ViewM>, state: &mut ViewT, element: &mut Self::Element) {
match self.data.take().unwrap() {
OneOfData::A(mut view) => match element {
OneOfData::A((last_view, elem)) => {
view.rebuild(cx, state, elem);
*last_view = view;
}
OneOfData::B(_) => {
let elem = view.build(cx, state);

let last_element = mem::replace(element, OneOfData::A((view, elem)));
match last_element {
OneOfData::B((mut last_view, last_elem)) => {
last_view.remove(cx, state, last_elem)
}
_ => unimplemented!(),
}
}
},
OneOfData::B(mut view) => match element {
OneOfData::A(_) => {
let elem = view.build(cx, state);

let last_element = mem::replace(element, OneOfData::B((view, elem)));
match last_element {
OneOfData::A((mut last_view, last_elem)) => {
last_view.remove(cx, state, last_elem)
}
_ => unimplemented!(),
}
}
OneOfData::B((last_view, elem)) => {
view.rebuild(cx, state, elem);
*last_view = view;
}
},
}
}

fn remove(&mut self, cx: &mut Context<ViewM>, state: &mut ViewT, element: Self::Element) {
match element {
OneOfData::A((mut view, elem)) => view.remove(cx, state, elem),
OneOfData::B((mut view, elem)) => view.remove(cx, state, elem),
}
}
}

impl<T, M, V, K> View<T, M> for Vec<(K, V)>
where
K: PartialEq,
Expand Down
8 changes: 4 additions & 4 deletions src/web/html.rs
Expand Up @@ -83,9 +83,10 @@ where
self.attrs.rebuild(cx, &mut element.0, &mut element.1)
}

fn remove(&mut self, _cx: &mut Context<M>, _state: &mut Web, _element: Self::Element) {
fn remove(&mut self, _cx: &mut Context<M>, _state: &mut Web, element: Self::Element) {
#[cfg(feature = "tracing")]
crate::remove_span!("Element");
element.0.element.remove();
}
}

Expand Down Expand Up @@ -167,7 +168,6 @@ where
_tree: &mut HtmlAttributes,
_element: &mut Self::Element,
) {

}

fn remove(
Expand Down Expand Up @@ -270,7 +270,7 @@ where

pub fn class<T>(name: T) -> Class<T>
where
T: AsRef<str> + PartialEq+ Clone,
T: AsRef<str> + PartialEq + Clone,
{
Class { name }
}
Expand All @@ -281,7 +281,7 @@ pub struct Class<T> {

impl<M, T> View<HtmlAttributes, M> for Class<T>
where
T: AsRef<str> + PartialEq + Clone,
T: AsRef<str> + PartialEq + Clone,
{
type Element = T;

Expand Down
17 changes: 12 additions & 5 deletions src/web/mod.rs
Expand Up @@ -56,7 +56,7 @@ impl<M> View<Web, M> for &'static str {

fn build(&mut self, _cx: &mut Context<M>, tree: &mut Web) -> Self::Element {
#[cfg(feature = "tracing")]
crate::build_span!("String");
crate::build_span!("&'static str");

let text = tree.document.create_text_node(self);
tree.parent.append_child(&text).unwrap();
Expand All @@ -66,17 +66,19 @@ impl<M> View<Web, M> for &'static str {

fn rebuild(&mut self, _cx: &mut Context<M>, _tree: &mut Web, element: &mut Self::Element) {
#[cfg(feature = "tracing")]
crate::rebuild_span!("String");
crate::rebuild_span!("&'static str");

if *self != element.0 {
element.0 = self;
element.1.set_text_content(Some(self));
}
}

fn remove(&mut self, _cx: &mut Context<M>, _state: &mut Web, _element: Self::Element) {
fn remove(&mut self, _cx: &mut Context<M>, _state: &mut Web, element: Self::Element) {
#[cfg(feature = "tracing")]
crate::remove_span!("String");
crate::remove_span!("&'static str");

element.1.remove();
}
}

Expand Down Expand Up @@ -105,5 +107,10 @@ impl<M> View<Web, M> for String {
}
}

fn remove(&mut self, _cx: &mut Context<M>, _state: &mut Web, _element: Self::Element) {}
fn remove(&mut self, _cx: &mut Context<M>, _state: &mut Web, element: Self::Element) {
#[cfg(feature = "tracing")]
crate::remove_span!("String");

element.1.remove();
}
}

0 comments on commit f238868

Please sign in to comment.