Change context api to panic with nice error message
This commit is contained in:
19 files changed
+96
-69
No files matched your search
@@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
global_context::{consume_context, current_scope_id},
|
||||
global_context::{current_scope_id, try_consume_context},
|
||||
innerlude::provide_context,
|
||||
use_hook, Element, IntoDynNode, Properties, ScopeId, Template, TemplateAttribute, TemplateNode,
|
||||
VNode,
|
||||
@@ -202,7 +202,7 @@ pub trait Throw<S = ()>: Sized {
|
||||
}
|
||||
|
||||
fn throw_error<T>(e: impl Debug + 'static) -> Option<T> {
|
||||
if let Some(cx) = consume_context::<ErrorBoundary>() {
|
||||
if let Some(cx) = try_consume_context::<ErrorBoundary>() {
|
||||
match current_scope_id() {
|
||||
Some(id) => cx.insert_error(id, Box::new(e), Backtrace::capture()),
|
||||
None => {
|
||||
|
||||
@@ -19,10 +19,17 @@ pub fn vdom_is_rendering() -> bool {
|
||||
}
|
||||
|
||||
/// Consume context from the current scope
|
||||
pub fn consume_context<T: 'static + Clone>() -> Option<T> {
|
||||
pub fn try_consume_context<T: 'static + Clone>() -> Option<T> {
|
||||
with_current_scope(|cx| cx.consume_context::<T>()).flatten()
|
||||
}
|
||||
|
||||
/// Consume context from the current scope
|
||||
pub fn consume_context<T: 'static + Clone>() -> T {
|
||||
with_current_scope(|cx| cx.consume_context::<T>())
|
||||
.flatten()
|
||||
.unwrap_or_else(|| panic!("Could not find context {}", std::any::type_name::<T>(),))
|
||||
}
|
||||
|
||||
/// Consume context from the current scope
|
||||
pub fn consume_context_from_scope<T: 'static + Clone>(scope_id: ScopeId) -> Option<T> {
|
||||
with_runtime(|rt| {
|
||||
|
||||
@@ -88,8 +88,8 @@ pub mod prelude {
|
||||
consume_context, consume_context_from_scope, current_scope_id, fc_to_builder, generation,
|
||||
has_context, needs_update, parent_scope, provide_context, provide_root_context,
|
||||
push_future, remove_future, schedule_update, schedule_update_any, spawn, spawn_forever,
|
||||
suspend, use_error_boundary, use_hook, AnyValue, Attribute, Component, Element,
|
||||
ErrorBoundary, Event, EventHandler, Fragment, HasAttributes, IntoAttributeValue,
|
||||
suspend, try_consume_context, use_error_boundary, use_hook, AnyValue, Attribute, Component,
|
||||
Element, ErrorBoundary, Event, EventHandler, Fragment, HasAttributes, IntoAttributeValue,
|
||||
IntoDynNode, Properties, Runtime, RuntimeGuard, ScopeId, ScopeState, Task, Template,
|
||||
TemplateAttribute, TemplateNode, Throw, VNode, VNodeInner, VirtualDom,
|
||||
};
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use crate::ScopeId;
|
||||
use slab::Slab;
|
||||
|
||||
mod task;
|
||||
mod wait;
|
||||
|
||||
@@ -33,7 +33,7 @@ use tao::platform::ios::WindowExtIOS;
|
||||
///
|
||||
/// This function will panic if it is called outside of the context of a Dioxus App.
|
||||
pub fn window() -> DesktopContext {
|
||||
dioxus_core::prelude::consume_context().unwrap()
|
||||
dioxus_core::prelude::consume_context()
|
||||
}
|
||||
|
||||
/// A handle to the [`DesktopService`] that can be passed around.
|
||||
|
||||
@@ -14,7 +14,7 @@ use wry::RequestAsyncResponder;
|
||||
|
||||
/// Get an imperative handle to the current window
|
||||
pub fn use_window() -> DesktopContext {
|
||||
use_hook(|| consume_context::<DesktopContext>()).unwrap()
|
||||
use_hook(|| consume_context::<DesktopContext>())
|
||||
}
|
||||
|
||||
/// Get a closure that executes any JavaScript in the WebView context.
|
||||
|
||||
@@ -58,8 +58,8 @@ macro_rules! to_owned {
|
||||
mod use_on_destroy;
|
||||
pub use use_on_destroy::*;
|
||||
|
||||
// mod use_context;
|
||||
// pub use use_context::*;
|
||||
mod use_context;
|
||||
pub use use_context::*;
|
||||
|
||||
mod use_coroutine;
|
||||
pub use use_coroutine::*;
|
||||
|
||||
@@ -1,20 +1,31 @@
|
||||
use dioxus_core::ScopeState;
|
||||
use dioxus_core::{
|
||||
prelude::{consume_context, provide_context, try_consume_context},
|
||||
use_hook,
|
||||
};
|
||||
|
||||
/// Consume some context in the tree, providing a sharable handle to the value
|
||||
///
|
||||
/// Does not regenerate the value if the value is changed at the parent.
|
||||
#[must_use]
|
||||
pub fn use_context<T: 'static + Clone>() -> Option<&T> {
|
||||
cx.use_hook(|| cx.consume_context::<T>()).as_ref()
|
||||
pub fn try_use_context<T: 'static + Clone>() -> Option<T> {
|
||||
use_hook(|| try_consume_context::<T>())
|
||||
}
|
||||
|
||||
/// Consume some context in the tree, providing a sharable handle to the value
|
||||
///
|
||||
/// Does not regenerate the value if the value is changed at the parent.
|
||||
#[must_use]
|
||||
pub fn use_context<T: 'static + Clone>() -> T {
|
||||
use_hook(|| consume_context::<T>())
|
||||
}
|
||||
|
||||
/// Provide some context via the tree and return a reference to it
|
||||
///
|
||||
/// Once the context has been provided, it is immutable. Mutations should be done via interior mutability.
|
||||
pub fn use_context_provider<T: 'static + Clone>(f: impl FnOnce() -> T) -> &T {
|
||||
cx.use_hook(|| {
|
||||
pub fn use_context_provider<T: 'static + Clone>(f: impl FnOnce() -> T) -> T {
|
||||
use_hook(|| {
|
||||
let val = f();
|
||||
cx.provide_context(val.clone());
|
||||
provide_context(val.clone());
|
||||
val
|
||||
})
|
||||
}
|
||||
@@ -96,7 +96,7 @@ where
|
||||
///
|
||||
/// See the docs for [`use_coroutine`] for more details.
|
||||
#[must_use]
|
||||
pub fn use_coroutine_handle<M: 'static>() -> Option<Coroutine<M>> {
|
||||
pub fn use_coroutine_handle<M: 'static>() -> Coroutine<M> {
|
||||
use_hook(|| consume_context::<Coroutine<M>>())
|
||||
}
|
||||
|
||||
@@ -118,6 +118,10 @@ impl<T> Coroutine<T> {
|
||||
let _ = self.tx.read().as_ref().unwrap().unbounded_send(msg);
|
||||
}
|
||||
|
||||
pub fn tx(&self) -> UnboundedSender<T> {
|
||||
self.tx.read().as_ref().unwrap().clone()
|
||||
}
|
||||
|
||||
/// Restart this coroutine
|
||||
///
|
||||
/// Forces the component to re-render, which will re-invoke the coroutine.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use dioxus_core::{prelude::consume_context, prelude::provide_root_context, use_hook};
|
||||
use dioxus_core::{prelude::provide_root_context, prelude::try_consume_context, use_hook};
|
||||
|
||||
///
|
||||
pub fn use_root_context<T: 'static + Clone>(new: impl FnOnce() -> T) -> T {
|
||||
use_hook(|| {
|
||||
consume_context::<T>()
|
||||
try_consume_context::<T>()
|
||||
// If no context is provided, create a new one at the root
|
||||
.unwrap_or_else(|| provide_root_context(new()).expect(" A runtime to exist"))
|
||||
})
|
||||
|
||||
@@ -35,7 +35,7 @@ type EvalCreator = Rc<dyn Fn(&str) -> Result<UseEval, EvalError>>;
|
||||
/// has access to most, if not all of your application data.**
|
||||
#[must_use]
|
||||
pub fn eval_provider() -> EvalCreator {
|
||||
let eval_provider = consume_context::<Rc<dyn EvalProvider>>().expect("evaluator not provided");
|
||||
let eval_provider = consume_context::<Rc<dyn EvalProvider>>();
|
||||
|
||||
Rc::new(move |script: &str| {
|
||||
eval_provider
|
||||
@@ -45,8 +45,7 @@ pub fn eval_provider() -> EvalCreator {
|
||||
}
|
||||
|
||||
pub fn eval(script: &str) -> Result<UseEval, EvalError> {
|
||||
let eval_provider = dioxus_core::prelude::consume_context::<Rc<dyn EvalProvider>>()
|
||||
.expect("evaluator not provided");
|
||||
let eval_provider = dioxus_core::prelude::consume_context::<Rc<dyn EvalProvider>>();
|
||||
|
||||
eval_provider
|
||||
.new_evaluator(script.to_string())
|
||||
|
||||
@@ -9,7 +9,7 @@ use crate::prelude::{ExternalNavigationFailure, IntoRoutable, RouterContext};
|
||||
/// Panics if there is no router present.
|
||||
pub fn navigator() -> Navigator {
|
||||
Navigator(
|
||||
dioxus_lib::prelude::consume_context::<RouterContext>()
|
||||
dioxus_lib::prelude::try_consume_context::<RouterContext>()
|
||||
.expect("A router must be present to use navigator"),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ impl<R> Clone for OutletContext<R> {
|
||||
|
||||
pub(crate) fn use_outlet_context<R: 'static>() -> OutletContext<R> {
|
||||
use_hook(|| {
|
||||
consume_context().unwrap_or(OutletContext::<R> {
|
||||
try_consume_context().unwrap_or(OutletContext::<R> {
|
||||
current_level: 1,
|
||||
_marker: std::marker::PhantomData,
|
||||
})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use dioxus_lib::prelude::{consume_context, use_hook};
|
||||
use dioxus_lib::prelude::{consume_context, try_consume_context, use_hook};
|
||||
|
||||
use crate::prelude::{Navigator, RouterContext};
|
||||
|
||||
@@ -51,7 +51,7 @@ use crate::prelude::{Navigator, RouterContext};
|
||||
#[must_use]
|
||||
pub fn use_navigator() -> Navigator {
|
||||
use_hook(|| {
|
||||
let router = consume_context::<RouterContext>()
|
||||
let router = try_consume_context::<RouterContext>()
|
||||
.expect("Must be called in a descendant of a Router component");
|
||||
|
||||
Navigator(router)
|
||||
|
||||
@@ -9,5 +9,5 @@ pub fn use_router() -> RouterContext {
|
||||
|
||||
/// Aquire the router without subscribing to updates.
|
||||
pub fn router() -> RouterContext {
|
||||
dioxus_lib::prelude::consume_context().unwrap()
|
||||
dioxus_lib::prelude::consume_context()
|
||||
}
|
||||
Reference in new issue
Block a user