feat: massage lifetimes

This commit is contained in:
Jonathan Kelley committed 2021-10-16 17:37:28 -04:00
1 parent 16dbf4a6f8
commit 9726a065b0
92 files changed
+250 -241

No files matched your search

+2 -2
View File
@@ -23,7 +23,7 @@ criterion_group!(mbenches, create_rows);
criterion_main!(mbenches);
fn create_rows(c: &mut Criterion) {
static App: FC<()> = |cx, _| {
static App: FC<()> = |(cx, _)| {
let mut rng = SmallRng::from_entropy();
let rows = (0..10_000_usize).map(|f| {
let label = Label::new(&mut rng);
@@ -57,7 +57,7 @@ struct RowProps {
row_id: usize,
label: Label,
}
fn Row<'a>(cx: Context<'a>, props: &RowProps) -> DomTree<'a> {
fn Row((cx, props): Component<RowProps>) -> DomTree {
let [adj, col, noun] = props.label.0;
cx.render(rsx! {
tr {
+1 -1
View File
@@ -6,7 +6,7 @@ fn main() {
println!("{}", dom);
}
pub static EXAMPLE: FC<()> = |cx, _| {
pub static EXAMPLE: FC<()> = |(cx, _)| {
let list = (0..10).map(|_f| LazyNodes::new(move |_f| todo!()));
cx.render(LazyNodes::new(move |cx| {
+1 -1
View File
@@ -5,7 +5,7 @@ fn main() {
dom.rebuild();
}
const App: FC<()> = |cx, props| {
const App: FC<()> = |(cx, props)| {
let id = cx.scope_id();
cx.submit_task(Box::pin(async move { id }));
+1 -1
View File
@@ -6,7 +6,7 @@ struct SomeContext {
}
#[allow(unused)]
static Example: FC<()> = |cx, props| {
static Example: FC<()> = |(cx, props)| {
todo!()
// let value = cx.use_context(|c: &SomeContext| c.items.last().unwrap());
+3 -2
View File
@@ -1,3 +1,4 @@
use dioxus::component::Component;
use dioxus::events::on::MouseEvent;
use dioxus_core as dioxus;
use dioxus_core::prelude::*;
@@ -12,7 +13,7 @@ fn main() {
assert!(g.edits.len() > 1);
}
static App: FC<()> = |cx, props| {
static App: FC<()> = |(cx, props)| {
let mut rng = SmallRng::from_entropy();
let rows = (0..10_000_usize).map(|f| {
let label = Label::new(&mut rng);
@@ -37,7 +38,7 @@ struct RowProps {
row_id: usize,
label: Label,
}
fn Row<'a>(cx: Context<'a>, props: &'a RowProps) -> DomTree<'a> {
fn Row((cx, props): Component<RowProps>) -> DomTree {
let handler = move |evt: MouseEvent| {
let g = evt.button;
};
+1 -1
View File
@@ -4,7 +4,7 @@ use dioxus_core::prelude::*;
#[async_std::main]
async fn main() {
static App: FC<()> = |cx, props| cx.render(LazyNodes::new(|f| f.text(format_args!("hello"))));
static App: FC<()> = |(cx, props)| cx.render(LazyNodes::new(|f| f.text(format_args!("hello"))));
let mut dom = VirtualDom::new(App);
+35 -1
View File
@@ -7,6 +7,40 @@
use crate::innerlude::{Context, DomTree, LazyNodes, FC};
/// A component is a wrapper around a Context and some Props that share a lifetime
///
///
/// # Example
///
/// With memoized state:
/// ```rust
/// struct State {}
///
/// fn Example((cx, props): Component<State>) -> DomTree {
/// // ...
/// }
/// ```
///
/// With borrowed state:
/// ```rust
/// struct State<'a> {
/// name: &'a str
/// }
///
/// fn Example<'a>((cx, props): Component<'a, State>) -> DomTree<'a> {
/// // ...
/// }
/// ```
///
/// With owned state as a closure:
/// ```rust
/// static Example: FC<()> = |(cx, props)| {
/// // ...
/// };
/// ```
///
pub type Component<'a, T> = (Context<'a>, &'a T);
/// Create inline fragments using Component syntax.
///
/// Fragments capture a series of children without rendering extra nodes.
@@ -29,7 +63,7 @@ use crate::innerlude::{Context, DomTree, LazyNodes, FC};
/// You want to use this free-function when your fragment needs a key and simply returning multiple nodes from rsx! won't cut it.
///
#[allow(non_upper_case_globals, non_snake_case)]
pub fn Fragment<'a>(cx: Context<'a>, _: &'a ()) -> DomTree<'a> {
pub fn Fragment((cx, _): Component<()>) -> DomTree {
cx.render(LazyNodes::new(|f| f.fragment_from_iter(cx.children())))
}
+6 -6
View File
@@ -69,7 +69,7 @@ impl<'src> Context<'src> {
/// ## Example
///
/// ```rust
/// const App: FC<()> = |cx, props|{
/// const App: FC<()> = |(cx, props)|{
/// cx.render(rsx!{
/// CustomCard {
/// h1 {}
@@ -78,7 +78,7 @@ impl<'src> Context<'src> {
/// })
/// }
///
/// const CustomCard: FC<()> = |cx, props|{
/// const CustomCard: FC<()> = |(cx, props)|{
/// cx.render(rsx!{
/// div {
/// h1 {"Title card"}
@@ -181,12 +181,12 @@ impl<'src> Context<'src> {
/// ```
/// struct SharedState(&'static str);
///
/// static App: FC<()> = |cx, props|{
/// static App: FC<()> = |(cx, props)|{
/// cx.provide_state(SharedState("world"));
/// rsx!(cx, Child {})
/// }
///
/// static Child: FC<()> = |cx, props|{
/// static Child: FC<()> = |(cx, props)|{
/// let state = cx.consume_state::<SharedState>();
/// rsx!(cx, div { "hello {state.0}" })
/// }
@@ -221,7 +221,7 @@ impl<'src> Context<'src> {
/// # Example
///
/// ```rust
/// static App: FC<()> = |cx, props| {
/// static App: FC<()> = |(cx, props)| {
/// todo!();
/// rsx!(cx, div { "Subtree {id}"})
/// };
@@ -238,7 +238,7 @@ impl<'src> Context<'src> {
/// # Example
///
/// ```rust
/// static App: FC<()> = |cx, props| {
/// static App: FC<()> = |(cx, props)| {
/// let id = cx.get_current_subtree();
/// rsx!(cx, div { "Subtree {id}"})
/// };
+1 -1
View File
@@ -18,7 +18,7 @@ use std::{any::Any, cell::RefCell, future::Future, ops::Deref, rc::Rc};
/// Returns the handle to the task and the value (if it is ready, else None).
///
/// ```
/// static Example: FC<()> = |cx, props| {
/// static Example: FC<()> = |(cx, props)| {
/// let (task, value) = use_task(|| async {
/// timer::sleep(Duration::from_secs(1)).await;
/// "Hello World"
+2 -2
View File
@@ -57,7 +57,7 @@ pub(crate) mod innerlude {
pub use crate::virtual_dom::*;
pub type DomTree<'a> = Option<VNode<'a>>;
pub type FC<P> = for<'a> fn(Context<'a>, &'a P) -> DomTree<'a>;
pub type FC<P> = for<'a> fn(Component<'a, P>) -> DomTree<'a>;
}
pub use crate::innerlude::{
@@ -67,7 +67,7 @@ pub use crate::innerlude::{
};
pub mod prelude {
pub use crate::component::{fc_to_builder, Fragment, Properties};
pub use crate::component::{fc_to_builder, Component, Fragment, Properties};
pub use crate::context::Context;
pub use crate::hooks::*;
pub use crate::innerlude::{DioxusElement, DomTree, LazyNodes, Mutations, NodeFactory, FC};
+1 -1
View File
@@ -526,7 +526,7 @@ impl<'a> NodeFactory<'a> {
let caller: &'a mut dyn for<'b> Fn(&'b Scope) -> DomTree<'b> =
bump.alloc(move |scope: &Scope| -> DomTree {
let props: &'_ P = unsafe { &*(raw_props as *const P) };
let res = component(Context { scope }, props);
let res = component((Context { scope }, props));
unsafe { std::mem::transmute(res) }
});
+5 -5
View File
@@ -60,7 +60,7 @@ impl Scope {
///
/// # Example
/// ```rust
/// let mut dom = VirtualDom::new(|cx, props|cx.render(rsx!{ div {} }));
/// let mut dom = VirtualDom::new(|(cx, props)|cx.render(rsx!{ div {} }));
/// dom.rebuild();
///
/// let base = dom.base_scope();
@@ -82,7 +82,7 @@ impl Scope {
/// # Example
///
/// ```rust
/// let mut dom = VirtualDom::new(|cx, props|cx.render(rsx!{ div {} }));
/// let mut dom = VirtualDom::new(|(cx, props)|cx.render(rsx!{ div {} }));
/// dom.rebuild();
///
/// let base = dom.base_scope();
@@ -110,7 +110,7 @@ impl Scope {
/// # Example
///
/// ```rust
/// let mut dom = VirtualDom::new(|cx, props|cx.render(rsx!{ div {} }));
/// let mut dom = VirtualDom::new(|(cx, props)|cx.render(rsx!{ div {} }));
/// dom.rebuild();
///
/// let base = dom.base_scope();
@@ -130,7 +130,7 @@ impl Scope {
/// # Example
///
/// ```rust
/// let mut dom = VirtualDom::new(|cx, props|cx.render(rsx!{ div {} }));
/// let mut dom = VirtualDom::new(|(cx, props)|cx.render(rsx!{ div {} }));
/// dom.rebuild();
///
/// let base = dom.base_scope();
@@ -148,7 +148,7 @@ impl Scope {
/// # Example
///
/// ```rust
/// let mut dom = VirtualDom::new(|cx, props|cx.render(rsx!{ div {} }));
/// let mut dom = VirtualDom::new(|(cx, props)|cx.render(rsx!{ div {} }));
/// dom.rebuild();
/// let base = dom.base_scope();
///
+7 -7
View File
@@ -33,7 +33,7 @@ use std::{any::Any, rc::Rc};
///
/// Example
/// ```rust
/// static App: FC<()> = |cx, props|{
/// static App: FC<()> = |(cx, props)|{
/// cx.render(rsx!{
/// div {
/// "Hello World"
@@ -145,7 +145,7 @@ impl VirtualDom {
// Safety: this callback is only valid for the lifetime of the root props
let root_caller: Rc<dyn Fn(&Scope) -> DomTree> = Rc::new(move |scope: &Scope| unsafe {
let props = _p.downcast_ref::<P>().unwrap();
std::mem::transmute(root(Context { scope }, props))
std::mem::transmute(root((Context { scope }, props)))
});
let scheduler = Scheduler::new(sender, receiver);
@@ -196,7 +196,7 @@ impl VirtualDom {
/// struct AppProps {
/// route: &'static str
/// }
/// static App: FC<AppProps> = |cx, props|cx.render(rsx!{ "route is {cx.route}" });
/// static App: FC<AppProps> = |(cx, props)|cx.render(rsx!{ "route is {cx.route}" });
///
/// let mut dom = VirtualDom::new_with_props(App, AppProps { route: "start" });
///
@@ -222,7 +222,7 @@ impl VirtualDom {
let root_caller: Box<dyn Fn(&Scope) -> DomTree> =
Box::new(move |scope: &Scope| unsafe {
let props: &'_ P = &*(props_ptr as *const P);
std::mem::transmute(root(Context { scope }, props))
std::mem::transmute(root((Context { scope }, props)))
});
root_scope.update_scope_dependencies(&root_caller, ScopeChildren(&[]));
@@ -246,7 +246,7 @@ impl VirtualDom {
///
/// # Example
/// ```
/// static App: FC<()> = |cx, props|cx.render(rsx!{ "hello world" });
/// static App: FC<()> = |(cx, props)|cx.render(rsx!{ "hello world" });
/// let mut dom = VirtualDom::new();
/// let edits = dom.rebuild();
///
@@ -271,7 +271,7 @@ impl VirtualDom {
/// value: Shared<&'static str>,
/// }
///
/// static App: FC<AppProps> = |cx, props|{
/// static App: FC<AppProps> = |(cx, props)|{
/// let val = cx.value.borrow();
/// cx.render(rsx! { div { "{val}" } })
/// };
@@ -333,7 +333,7 @@ impl VirtualDom {
/// # Example
///
/// ```no_run
/// static App: FC<()> = |cx, props|rsx!(cx, div {"hello"} );
/// static App: FC<()> = |(cx, props)|rsx!(cx, div {"hello"} );
/// let mut dom = VirtualDom::new(App);
/// loop {
/// let deadline = TimeoutFuture::from_ms(16);
+3 -3
View File
@@ -3,7 +3,7 @@ use dioxus_core as dioxus;
use dioxus_core_macro::*;
use dioxus_html as dioxus_elements;
static Parent: FC<()> = |cx, props| {
static Parent: FC<()> = |(cx, props)| {
let value = cx.use_hook(|_| String::new(), |f| &*f, |_| {});
cx.render(rsx! {
@@ -21,7 +21,7 @@ struct ChildProps<'a> {
name: &'a String,
}
fn Child<'a>(cx: Context<'a>, props: &'a ChildProps) -> DomTree<'a> {
fn Child<'a>((cx, props): Component<'a, ChildProps>) -> DomTree<'a> {
cx.render(rsx! {
div {
h1 { "it's nested" }
@@ -35,7 +35,7 @@ struct Grandchild<'a> {
name: &'a String,
}
fn Child2<'a>(cx: Context<'a>, props: &Grandchild) -> DomTree<'a> {
fn Child2<'a>((cx, props): Component<'a, Grandchild>) -> DomTree<'a> {
cx.render(rsx! {
div { "Hello {props.name}!" }
})
+9 -9
View File
@@ -19,7 +19,7 @@ fn new_dom<P: 'static + Send>(app: FC<P>, props: P) -> VirtualDom {
#[test]
fn test_original_diff() {
static APP: FC<()> = |cx, props| {
static APP: FC<()> = |(cx, props)| {
cx.render(rsx! {
div {
div {
@@ -55,7 +55,7 @@ fn test_original_diff() {
#[test]
fn create() {
static APP: FC<()> = |cx, props| {
static APP: FC<()> = |(cx, props)| {
cx.render(rsx! {
div {
div {
@@ -118,7 +118,7 @@ fn create() {
#[test]
fn create_list() {
static APP: FC<()> = |cx, props| {
static APP: FC<()> = |(cx, props)| {
cx.render(rsx! {
{(0..3).map(|f| rsx!{ div {
"hello"
@@ -167,7 +167,7 @@ fn create_list() {
#[test]
fn create_simple() {
static APP: FC<()> = |cx, props| {
static APP: FC<()> = |(cx, props)| {
cx.render(rsx! {
div {}
div {}
@@ -205,7 +205,7 @@ fn create_simple() {
}
#[test]
fn create_components() {
static App: FC<()> = |cx, props| {
static App: FC<()> = |(cx, props)| {
cx.render(rsx! {
Child { "abc1" }
Child { "abc2" }
@@ -213,7 +213,7 @@ fn create_components() {
})
};
static Child: FC<()> = |cx, props| {
static Child: FC<()> = |(cx, props)| {
cx.render(rsx! {
h1 {}
div { {cx.children()} }
@@ -266,7 +266,7 @@ fn create_components() {
}
#[test]
fn anchors() {
static App: FC<()> = |cx, props| {
static App: FC<()> = |(cx, props)| {
cx.render(rsx! {
{true.then(|| rsx!{ div { "hello" } })}
{false.then(|| rsx!{ div { "goodbye" } })}
@@ -295,13 +295,13 @@ fn anchors() {
#[test]
fn suspended() {
static App: FC<()> = |cx, props| {
static App: FC<()> = |(cx, props)| {
let val = use_suspense(
cx,
|| async {
//
},
|cx, _| cx.render(rsx! { "hi "}),
|cx, p| cx.render(rsx! { "hi "}),
);
cx.render(rsx! { {val} })
};
+2 -2
View File
@@ -16,7 +16,7 @@ const IS_LOGGING_ENABLED: bool = true;
#[test]
fn please_work() {
static App: FC<()> = |cx, props| {
static App: FC<()> = |(cx, props)| {
cx.render(rsx! {
div {
hidden: "true"
@@ -30,7 +30,7 @@ fn please_work() {
})
};
static Child: FC<()> = |cx, props| {
static Child: FC<()> = |(cx, props)| {
cx.render(rsx! {
div { "child" }
})
+1 -1
View File
@@ -8,7 +8,7 @@ use dioxus_html as dioxus_elements;
#[async_std::test]
async fn event_queue_works() {
static App: FC<()> = |cx, props| {
static App: FC<()> = |(cx, props)| {
cx.render(rsx! {
div { "hello world" }
})
+1 -1
View File
@@ -10,7 +10,7 @@ type Shared<T> = Rc<RefCell<T>>;
#[test]
fn sample_refs() {
// static App: FC<()> = |cx, props|{
// static App: FC<()> = |(cx, props)|{
// let div_ref = use_node_ref::<MyRef, _>(cx);
// cx.render(rsx! {
+1 -1
View File
@@ -20,7 +20,7 @@ fn manual_diffing() {
value: Shared<&'static str>,
}
static App: FC<AppProps> = |cx, props| {
static App: FC<AppProps> = |(cx, props)| {
let val = props.value.lock().unwrap();
cx.render(rsx! { div { "{val}" } })
};
+2 -2
View File
@@ -17,12 +17,12 @@ fn new_dom() -> TestDom {
fn shared_state_test() {
struct MySharedState(&'static str);
static App: FC<()> = |cx, props| {
static App: FC<()> = |(cx, props)| {
cx.provide_state(MySharedState("world!"));
rsx!(cx, Child {})
};
static Child: FC<()> = |cx, props| {
static Child: FC<()> = |(cx, props)| {
let shared = cx.consume_state::<MySharedState>()?;
rsx!(cx, "Hello, {shared.0}")
};
+7 -7
View File
@@ -15,7 +15,7 @@ use dioxus_html as dioxus_elements;
#[test]
fn app_runs() {
static App: FC<()> = |cx, props| {
static App: FC<()> = |(cx, props)| {
//
cx.render(rsx!( div{"hello"} ))
};
@@ -26,7 +26,7 @@ fn app_runs() {
#[test]
fn fragments_work() {
static App: FC<()> = |cx, props| {
static App: FC<()> = |(cx, props)| {
cx.render(rsx!(
div{"hello"}
div{"goodbye"}
@@ -40,7 +40,7 @@ fn fragments_work() {
#[test]
fn lists_work() {
static App: FC<()> = |cx, props| {
static App: FC<()> = |(cx, props)| {
cx.render(rsx!(
h1 {"hello"}
{(0..6).map(|f| rsx!(span{ "{f}" }))}
@@ -53,7 +53,7 @@ fn lists_work() {
#[test]
fn conditional_rendering() {
static App: FC<()> = |cx, props| {
static App: FC<()> = |(cx, props)| {
cx.render(rsx!(
h1 {"hello"}
{true.then(|| rsx!(span{ "a" }))}
@@ -70,13 +70,13 @@ fn conditional_rendering() {
#[test]
fn child_components() {
static App: FC<()> = |cx, props| {
static App: FC<()> = |(cx, props)| {
cx.render(rsx!(
{true.then(|| rsx!(Child { }))}
{false.then(|| rsx!(Child { }))}
))
};
static Child: FC<()> = |cx, props| {
static Child: FC<()> = |(cx, props)| {
cx.render(rsx!(
h1 {"hello"}
h1 {"goodbye"}
@@ -89,7 +89,7 @@ fn child_components() {
#[test]
fn suspended_works() {
static App: FC<()> = |cx, props| {
static App: FC<()> = |(cx, props)| {
let title = use_suspense(cx, || async { "bob" }, |cx, f| cx.render(rsx! { "{f}"}));
cx.render(rsx!("hello" { title }))
};