|
@@ -1,6 +1,8 @@
|
|
|
-use dioxus_core::{Component, Element, LazyNodes, Scope, VNode};
|
|
|
+use captuered_context::CapturedContext;
|
|
|
+use dioxus_core::{Component, Element, LazyNodes, NodeFactory, Scope, ScopeState, VNode};
|
|
|
use error::Error;
|
|
|
use interperter::build;
|
|
|
+use lazy_static::lazy_static;
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
use std::collections::HashMap;
|
|
|
use std::panic::Location;
|
|
@@ -13,6 +15,12 @@ mod elements;
|
|
|
pub mod error;
|
|
|
mod interperter;
|
|
|
|
|
|
+lazy_static! {
|
|
|
+ /// This a a global store of the current
|
|
|
+ // Global mutable data is genrally not great, but it allows users to not worry about passing down the text RsxContex every time they switch to hot reloading.
|
|
|
+ pub static ref RSX_CONTEXT: RsxContext = RsxContext::new(RsxData::default());
|
|
|
+}
|
|
|
+
|
|
|
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
|
|
pub struct CodeLocation {
|
|
|
pub file: String,
|
|
@@ -20,6 +28,34 @@ pub struct CodeLocation {
|
|
|
pub column: u32,
|
|
|
}
|
|
|
|
|
|
+pub fn resolve_scope<'a>(
|
|
|
+ location: CodeLocation,
|
|
|
+ rsx: &'static str,
|
|
|
+ captured: CapturedContext<'a>,
|
|
|
+ factory: NodeFactory<'a>,
|
|
|
+) -> VNode<'a> {
|
|
|
+ let rsx_text_index = &*RSX_CONTEXT;
|
|
|
+ // only the insert the rsx text once
|
|
|
+ if !rsx_text_index.read().hm.contains_key(&location) {
|
|
|
+ rsx_text_index.insert(location.clone(), rsx.to_string());
|
|
|
+ }
|
|
|
+ if let Some(text) = {
|
|
|
+ let read = rsx_text_index.read();
|
|
|
+ // clone prevents deadlock on nested rsx calls
|
|
|
+ read.hm.get(&location).cloned()
|
|
|
+ } {
|
|
|
+ match interpert_rsx(factory, &text, captured) {
|
|
|
+ Ok(vnode) => vnode,
|
|
|
+ Err(err) => {
|
|
|
+ rsx_text_index.report_error(err);
|
|
|
+ factory.text(format_args!(""))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ panic!("rsx: line number {:?} not found in rsx index", location);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
pub fn interpert_rsx<'a, 'b>(
|
|
|
factory: dioxus_core::NodeFactory<'a>,
|
|
|
text: &str,
|
|
@@ -47,9 +83,10 @@ pub struct RsxContext {
|
|
|
data: Arc<RwLock<RsxData>>,
|
|
|
}
|
|
|
|
|
|
+#[derive(Default)]
|
|
|
pub struct RsxData {
|
|
|
pub hm: HashMap<CodeLocation, String>,
|
|
|
- pub error_handler: Box<dyn ErrorHandler + Send + Sync>,
|
|
|
+ pub error_handler: Option<Box<dyn ErrorHandler>>,
|
|
|
}
|
|
|
|
|
|
impl std::fmt::Debug for RsxData {
|
|
@@ -74,11 +111,17 @@ impl RsxContext {
|
|
|
}
|
|
|
|
|
|
pub fn report_error(&self, error: Error) {
|
|
|
- self.data.write().unwrap().error_handler.handle_error(error)
|
|
|
+ if let Some(handler) = &self.data.write().unwrap().error_handler {
|
|
|
+ handler.handle_error(error)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ pub fn set_error_handler(&self, handler: impl ErrorHandler + 'static) {
|
|
|
+ self.data.write().unwrap().error_handler = Some(Box::new(handler));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-pub trait ErrorHandler {
|
|
|
+pub trait ErrorHandler: Send + Sync {
|
|
|
fn handle_error(&self, err: Error);
|
|
|
}
|
|
|
|