chore: rollback to option instead of anyhow

This commit is contained in:
Jonathan Kelley 2022-12-19 18:06:13 -08:00
parent d6804884ab
commit d3be971f4e
21 changed files with 45 additions and 56 deletions

View file

@ -26,7 +26,7 @@ struct ClickableProps<'a> {
// ANCHOR: Clickable
fn Clickable<'a>(cx: Scope<'a, ClickableProps<'a>>) -> Element {
match cx.props.children {
Ok(VNode { dynamic_nodes, .. }) => {
Some(VNode { dynamic_nodes, .. }) => {
todo!("render some stuff")
}
_ => {

View file

@ -31,13 +31,12 @@ futures-channel = "0.3.21"
indexmap = "1.7"
# Serialize the Edits for use in Webview/Liveview instances
serde = { version = "1", features = ["derive"], optional = true }
anyhow = "1.0.66"
smallbox = "0.8.1"
log = "0.4.17"
# Serialize the Edits for use in Webview/Liveview instances
serde = { version = "1", features = ["derive"], optional = true }
[dev-dependencies]
tokio = { version = "*", features = ["full"] }
dioxus = { path = "../dioxus" }

View file

@ -81,12 +81,12 @@ impl VirtualDom {
self.ensure_drop_safety(id);
if let Some(root) = self.scopes[id.0].as_ref().try_root_node() {
if let RenderReturn::Sync(Ok(node)) = unsafe { root.extend_lifetime_ref() } {
if let RenderReturn::Sync(Some(node)) = unsafe { root.extend_lifetime_ref() } {
self.drop_scope_inner(node)
}
}
if let Some(root) = unsafe { self.scopes[id.0].as_ref().previous_frame().try_load_node() } {
if let RenderReturn::Sync(Ok(node)) = unsafe { root.extend_lifetime_ref() } {
if let RenderReturn::Sync(Some(node)) = unsafe { root.extend_lifetime_ref() } {
self.drop_scope_inner(node)
}
}

View file

@ -354,8 +354,8 @@ impl<'b> VirtualDom {
use RenderReturn::*;
match return_nodes {
Sync(Ok(t)) => self.mount_component(scope, template, t, idx),
Sync(Err(_e)) => todo!("Propogate error upwards"),
Sync(Some(t)) => self.mount_component(scope, template, t, idx),
Sync(None) => todo!("Propogate error upwards"),
Async(_) => self.mount_component_placeholder(template, idx, scope),
}
}

View file

@ -33,26 +33,26 @@ impl<'b> VirtualDom {
use RenderReturn::{Async, Sync};
match (old, new) {
(Sync(Ok(l)), Sync(Ok(r))) => self.diff_node(l, r),
(Sync(Some(l)), Sync(Some(r))) => self.diff_node(l, r),
// Err cases
(Sync(Ok(l)), Sync(Err(e))) => self.diff_ok_to_err(l, e),
(Sync(Err(e)), Sync(Ok(r))) => self.diff_err_to_ok(e, r),
(Sync(Err(_eo)), Sync(Err(_en))) => { /* nothing */ }
(Sync(Some(l)), Sync(None)) => self.diff_ok_to_err(l),
(Sync(None), Sync(Some(r))) => self.diff_err_to_ok(r),
(Sync(None), Sync(None)) => { /* nothing */ }
// Async
(Sync(Ok(_l)), Async(_)) => todo!(),
(Sync(Err(_e)), Async(_)) => todo!(),
(Async(_), Sync(Ok(_r))) => todo!(),
(Async(_), Sync(Err(_e))) => { /* nothing */ }
(Sync(Some(_l)), Async(_)) => todo!(),
(Sync(None), Async(_)) => todo!(),
(Async(_), Sync(Some(_r))) => todo!(),
(Async(_), Sync(None)) => { /* nothing */ }
(Async(_), Async(_)) => { /* nothing */ }
};
}
self.scope_stack.pop();
}
fn diff_ok_to_err(&mut self, _l: &'b VNode<'b>, _e: &anyhow::Error) {}
fn diff_err_to_ok(&mut self, _e: &anyhow::Error, _l: &'b VNode<'b>) {}
fn diff_ok_to_err(&mut self, _l: &'b VNode<'b>) {}
fn diff_err_to_ok(&mut self, _l: &'b VNode<'b>) {}
fn diff_node(&mut self, left_template: &'b VNode<'b>, right_template: &'b VNode<'b>) {
// If the templates are the same, we don't need to do anything, nor do we want to
@ -679,7 +679,7 @@ impl<'b> VirtualDom {
Component(comp) => {
let scope = comp.scope.get().unwrap();
match unsafe { self.scopes[scope.0].root_node().extend_lifetime_ref() } {
RenderReturn::Sync(Ok(node)) => self.push_all_real_nodes(node),
RenderReturn::Sync(Some(node)) => self.push_all_real_nodes(node),
_ => todo!(),
}
}
@ -856,7 +856,7 @@ impl<'b> VirtualDom {
let scope = comp.scope.take().unwrap();
match unsafe { self.scopes[scope.0].root_node().extend_lifetime_ref() } {
RenderReturn::Sync(Ok(t)) => {
RenderReturn::Sync(Some(t)) => {
println!("Removing component node sync {:?}", gen_muts);
self.remove_node(t, gen_muts)
}
@ -886,7 +886,7 @@ impl<'b> VirtualDom {
Some(Component(comp)) => {
let scope = comp.scope.get().unwrap();
match unsafe { self.scopes[scope.0].root_node().extend_lifetime_ref() } {
RenderReturn::Sync(Ok(t)) => self.find_first_element(t),
RenderReturn::Sync(Some(t)) => self.find_first_element(t),
_ => todo!("cannot handle nonstandard nodes"),
}
}
@ -902,7 +902,7 @@ impl<'b> VirtualDom {
Some(Component(comp)) => {
let scope = comp.scope.get().unwrap();
match unsafe { self.scopes[scope.0].root_node().extend_lifetime_ref() } {
RenderReturn::Sync(Ok(t)) => self.find_last_element(t),
RenderReturn::Sync(Some(t)) => self.find_last_element(t),
_ => todo!("cannot handle nonstandard nodes"),
}
}

View file

@ -5,7 +5,7 @@ use crate::ScopeId;
/// A boundary that will capture any errors from child components
#[allow(dead_code)]
pub struct ErrorBoundary {
error: RefCell<Option<(anyhow::Error, ScopeId)>>,
error: RefCell<Option<ScopeId>>,
id: ScopeId,
}

View file

@ -27,8 +27,8 @@ use crate::innerlude::*;
/// 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: Scope<'a, FragmentProps<'a>>) -> Element {
let children = cx.props.0.as_ref().map_err(|e| anyhow::anyhow!("{}", e))?;
Ok(VNode {
let children = cx.props.0.as_ref()?;
Some(VNode {
key: children.key,
parent: children.parent,
template: children.template,
@ -95,7 +95,7 @@ impl<'a> Properties for FragmentProps<'a> {
type Builder = FragmentBuilder<'a, false>;
const IS_STATIC: bool = false;
fn builder() -> Self::Builder {
FragmentBuilder(VNode::empty())
FragmentBuilder(None)
}
unsafe fn memoize(&self, _other: &Self) -> bool {
false

View file

@ -34,10 +34,10 @@ pub(crate) mod innerlude {
pub use crate::scopes::*;
pub use crate::virtual_dom::*;
/// An [`Element`] is a possibly-errored [`VNode`] created by calling `render` on [`Scope`] or [`ScopeState`].
/// An [`Element`] is a possibly-none [`VNode`] created by calling `render` on [`Scope`] or [`ScopeState`].
///
/// An Errored [`Element`] will propagate the error to the nearest error boundary.
pub type Element<'a> = Result<VNode<'a>, anyhow::Error>;
pub type Element<'a> = Option<VNode<'a>>;
/// A [`Component`] is a function that takes a [`Scope`] and returns an [`Element`].
///

View file

@ -58,7 +58,7 @@ pub struct VNode<'a> {
impl<'a> VNode<'a> {
/// Create a template with no nodes that will be skipped over during diffing
pub fn empty() -> Element<'a> {
Ok(VNode {
Some(VNode {
key: None,
parent: None,
root_ids: &[],
@ -466,16 +466,6 @@ impl<'a> IntoDynNode<'a> for DynamicNode<'a> {
}
}
// An element that's an error is currently lost into the ether
impl<'a> IntoDynNode<'a> for Element<'a> {
fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
match self {
Ok(val) => val.into_vnode(_cx),
_ => DynamicNode::default(),
}
}
}
impl<'a, T: IntoDynNode<'a>> IntoDynNode<'a> for Option<T> {
fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
match self {
@ -488,7 +478,7 @@ impl<'a, T: IntoDynNode<'a>> IntoDynNode<'a> for Option<T> {
impl<'a> IntoDynNode<'a> for &Element<'a> {
fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
match self.as_ref() {
Ok(val) => val.clone().into_vnode(_cx),
Some(val) => val.clone().into_vnode(_cx),
_ => DynamicNode::default(),
}
}
@ -542,7 +532,7 @@ impl<'a> IntoTemplate<'a> for VNode<'a> {
impl<'a> IntoTemplate<'a> for Element<'a> {
fn into_template(self, _cx: &'a ScopeState) -> VNode<'a> {
match self {
Ok(val) => val.into_template(_cx),
Some(val) => val.into_template(_cx),
_ => VNode::empty().unwrap(),
}
}

View file

@ -78,7 +78,7 @@ impl VirtualDom {
fiber.waiting_on.borrow_mut().remove(&id);
if let RenderReturn::Sync(Ok(template)) = ret {
if let RenderReturn::Sync(Some(template)) = ret {
let mutations_ref = &mut fiber.mutations.borrow_mut();
let mutations = &mut **mutations_ref;
let template: &VNode = unsafe { std::mem::transmute(template) };

View file

@ -390,7 +390,7 @@ impl<'src> ScopeState {
}
}
Ok(element)
Some(element)
}
/// Create a dynamic text node using [`Arguments`] and the [`ScopeState`]'s internal [`Bump`] allocator

View file

@ -477,7 +477,7 @@ impl VirtualDom {
pub fn rebuild(&mut self) -> Mutations {
match unsafe { self.run_scope(ScopeId(0)).extend_lifetime_ref() } {
// Rebuilding implies we append the created elements to the root
RenderReturn::Sync(Ok(node)) => {
RenderReturn::Sync(Some(node)) => {
let m = self.create_scope(ScopeId(0), node);
self.mutations.edits.push(Mutation::AppendChildren {
id: ElementId(0),
@ -485,7 +485,7 @@ impl VirtualDom {
});
}
// If an error occurs, we should try to render the default error component and context where the error occured
RenderReturn::Sync(Err(e)) => panic!("Cannot catch errors during rebuild {:?}", e),
RenderReturn::Sync(None) => panic!("Cannot catch errors during rebuild"),
RenderReturn::Async(_) => unreachable!("Root scope cannot be an async component"),
}

View file

@ -9,7 +9,7 @@ fn app(cx: Scope) -> Element {
_ => unreachable!(),
};
let value = raw.parse::<f32>()?;
let value = raw.parse::<f32>().unwrap();
cx.render(rsx! {
div { "hello {value}" }

View file

@ -47,5 +47,5 @@ pub fn Redirect<'a>(cx: Scope<'a, RedirectProps<'a>>) -> Element {
router.replace_route(cx.props.to, None, None);
}
cx.render(rsx!(()))
None
}

View file

@ -52,6 +52,6 @@ pub fn Route<'a>(cx: Scope<'a, RouteProps<'a>>) -> Element {
cx.render(rsx!(&cx.props.children))
} else {
log::debug!("Route should *not* render: {:?}", cx.scope_id());
cx.render(rsx!(()))
None
}
}

View file

@ -171,7 +171,7 @@ impl ToTokens for Component {
toks.append_all(quote! {
.children(
Ok({ #renderer })
Some({ #renderer })
)
});
}

View file

@ -70,7 +70,7 @@ impl ToTokens for CallBody {
if self.inline_cx {
out_tokens.append_all(quote! {
Ok({
Some({
let __cx = cx;
#body
})

View file

@ -23,7 +23,7 @@ pub fn render_lazy(f: LazyNodes<'_, '_>) -> String {
fn lazy_app<'a>(cx: Scope<'a, RootProps<'static, 'static>>) -> Element<'a> {
let lazy = cx.props.caller.take().unwrap();
let lazy: LazyNodes = unsafe { std::mem::transmute(lazy) };
Ok(lazy.call(cx))
Some(lazy.call(cx))
}
let props: RootProps = unsafe {

View file

@ -51,7 +51,7 @@ impl Renderer {
) -> std::fmt::Result {
// We should never ever run into async or errored nodes in SSR
// Error boundaries and suspense boundaries will convert these to sync
if let RenderReturn::Sync(Ok(node)) = dom.get_scope(scope).unwrap().root_node() {
if let RenderReturn::Sync(Some(node)) = dom.get_scope(scope).unwrap().root_node() {
self.render_template(buf, dom, node)?
};
@ -89,7 +89,7 @@ impl Renderer {
let scope = dom.get_scope(id).unwrap();
let node = scope.root_node();
match node {
RenderReturn::Sync(Ok(node)) => {
RenderReturn::Sync(Some(node)) => {
self.render_template(buf, dom, node)?
}
_ => todo!(

View file

@ -17,7 +17,7 @@ fn app(cx: Scope) -> Element {
width: "100%",
background_color: "hsl({hue}, 70%, {brightness}%)",
onmousemove: move |evt| {
if let RenderReturn::Sync(Ok(node)) = cx.root_node() {
if let RenderReturn::Sync(Some(node)) = cx.root_node() {
if let Some(id) = node.root_ids[0].get() {
let node = tui_query.get(id);
let Size{width, height} = node.size().unwrap();

View file

@ -10,7 +10,7 @@ use dioxus_core::{ElementId, RenderReturn, Scope};
pub use input::*;
pub(crate) fn get_root_id<T>(cx: Scope<T>) -> Option<ElementId> {
if let RenderReturn::Sync(Ok(sync)) = cx.root_node() {
if let RenderReturn::Sync(Some(sync)) = cx.root_node() {
sync.root_ids.get(0).and_then(|id| id.get())
} else {
None