diff --git a/crates/concoct-web/src/html.rs b/crates/concoct-web/src/html.rs
index 6768f259..378ce0f5 100644
--- a/crates/concoct-web/src/html.rs
+++ b/crates/concoct-web/src/html.rs
@@ -1,8 +1,8 @@
use super::WebContext;
use concoct::{
- body::Child,
+ view::Child,
hook::{use_context, use_on_drop, use_provider, use_ref},
- Body, View,
+ View, ViewBuilder,
};
use std::{borrow::Cow, cell::RefCell, rc::Rc};
use web_sys::{
@@ -13,7 +13,7 @@ use web_sys::{
macro_rules! make_tag_fns {
($($name:tt),*) => {
$(
- pub fn $name(child: C) -> Html {
+ pub fn $name(child: C) -> Html {
Html::new(stringify!($name), child)
}
)*
@@ -108,8 +108,8 @@ impl Html {
);
}
-impl View for Html {
- fn body(&self) -> impl Body {
+impl ViewBuilder for Html {
+ fn build(&self) -> impl View {
let data = use_ref(|| RefCell::new(Data::default()));
let mut data_ref = data.borrow_mut();
diff --git a/crates/concoct-web/src/lib.rs b/crates/concoct-web/src/lib.rs
index 4690f333..882b1389 100644
--- a/crates/concoct-web/src/lib.rs
+++ b/crates/concoct-web/src/lib.rs
@@ -1,6 +1,6 @@
use concoct::{
hook::{use_context, use_on_drop, use_provider, use_ref},
- Body, TextViewContext, View,
+ View, TextViewContext, ViewBuilder,
};
use std::{cell::RefCell, rc::Rc};
use web_sys::{Document, Node, Text, Window};
@@ -17,8 +17,8 @@ pub struct WebRoot {
pub body: Rc,
}
-impl View for WebRoot {
- fn body(&self) -> impl Body {
+impl ViewBuilder for WebRoot {
+ fn build(&self) -> impl View {
let window = web_sys::window().unwrap();
let document = window.document().unwrap();
let body = document.body().unwrap();
@@ -58,7 +58,7 @@ impl View for WebRoot {
}
}
-pub async fn run(view: impl View) {
+pub async fn run(view: impl ViewBuilder) {
concoct::run(WebRoot {
body: Rc::new(view),
})
diff --git a/crates/concoct/src/body.rs b/crates/concoct/src/body.rs
deleted file mode 100644
index 674bff40..00000000
--- a/crates/concoct/src/body.rs
+++ /dev/null
@@ -1,87 +0,0 @@
-use crate::{Node, Tree, View};
-use std::{cell::RefCell, hash::Hash, rc::Rc};
-
-pub trait Body: 'static {
- fn into_tree(self) -> impl Tree;
-}
-
-impl Body for Option {
- fn into_tree(self) -> impl Tree {
- self.map(|me| me.into_tree())
- }
-}
-
-impl Body for Vec<(K, B)> {
- fn into_tree(self) -> impl Tree {
- self.into_iter()
- .map(|(key, body)| (key, body.into_tree()))
- .collect::>()
- }
-}
-
-pub struct Child {
- cell: Rc>>,
-}
-
-impl Child {
- pub fn new(body: B) -> Self {
- Self {
- cell: Rc::new(RefCell::new(Some(body))),
- }
- }
-}
-
-impl Clone for Child {
- fn clone(&self) -> Self {
- Self {
- cell: self.cell.clone(),
- }
- }
-}
-
-impl Body for Child {
- fn into_tree(self) -> impl Tree {
- self.cell.take().unwrap().into_tree()
- }
-}
-
-pub struct Empty;
-
-impl Body for Empty {
- fn into_tree(self) -> impl Tree {
- self
- }
-}
-
-impl Body for V {
- fn into_tree(self) -> impl Tree {
- Node {
- view: self,
- body: None,
- builder: |me: &'static V| me.body().into_tree(),
- scope: None,
- key: None,
- }
- }
-}
-
-macro_rules! impl_body_for_tuple {
- ($($t:tt : $idx:tt),*) => {
- impl<$($t: Body),*> Body for ($($t),*) {
- fn into_tree(self) -> impl Tree {
- ($( self.$idx.into_tree() ),*)
-
- }
- }
- };
-}
-
-impl_body_for_tuple!(V1: 0, V2: 1);
-impl_body_for_tuple!(V1: 0, V2: 1, V3: 2);
-impl_body_for_tuple!(V1: 0, V2: 1, V3: 2, V4: 3);
-impl_body_for_tuple!(V1: 0, V2: 1, V3: 2, V4: 3, V5: 4);
-impl_body_for_tuple!(V1: 0, V2: 1, V3: 2, V4: 3, V5: 4, V6: 5);
-impl_body_for_tuple!(V1: 0, V2: 1, V3: 2, V4: 3, V5: 4, V6: 5, V7: 6);
-impl_body_for_tuple!(V1: 0, V2: 1, V3: 2, V4: 3, V5: 4, V6: 5, V7: 6, V8: 7);
-impl_body_for_tuple!(V1: 0, V2: 1, V3: 2, V4: 3, V5: 4, V6: 5, V7: 6, V8: 7, V9: 8);
-impl_body_for_tuple!(V1: 0, V2: 1, V3: 2, V4: 3, V5: 4, V6: 5, V7: 6, V8: 7, V9: 8, V10: 9);
diff --git a/crates/concoct/src/hook/use_state.rs b/crates/concoct/src/hook/use_state.rs
index fd988011..d9fa10bd 100644
--- a/crates/concoct/src/hook/use_state.rs
+++ b/crates/concoct/src/hook/use_state.rs
@@ -1,6 +1,6 @@
use super::use_ref;
use crate::Context;
-use std::{cell::RefCell, rc::Rc};
+use std::cell::RefCell;
/// Hook to create render state.
///
diff --git a/crates/concoct/src/lib.rs b/crates/concoct/src/lib.rs
index 23587314..ef4965bf 100644
--- a/crates/concoct/src/lib.rs
+++ b/crates/concoct/src/lib.rs
@@ -2,19 +2,23 @@ use rustc_hash::FxHasher;
use slotmap::{DefaultKey, SlotMap};
use std::any::{Any, TypeId};
use std::borrow::Cow;
-use std::collections::{HashMap, HashSet, VecDeque};
+use std::collections::{HashMap, VecDeque};
use std::hash::{Hash, Hasher};
use std::task::{Poll, Waker};
-use std::{cell::RefCell, mem, rc::Rc};
-
-pub mod body;
-pub use self::body::Body;
-use body::Empty;
+use std::{cell::RefCell, rc::Rc};
pub mod hook;
+mod tree;
+pub(crate) use tree::Node;
+pub use tree::Tree;
+
+mod view_builder;
+pub use self::view_builder::ViewBuilder;
+
pub mod view;
pub use self::view::View;
+use view::Empty;
#[derive(Default)]
struct ScopeInner {
@@ -80,144 +84,6 @@ thread_local! {
static CONTEXT: RefCell