clean up and document items

This commit is contained in:
Demonthos committed 2022-06-11 20:06:50 -05:00
1 parent 71d31556e5
commit 8ed8758d35
7 files changed
+59 -59

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
use crate::elements::*; use crate::elements::*;
// find the mapped attribute name // map the rsx name of the attribute to the html name of the attribute and the namespace that contains it
pub fn attrbute_to_static_str(attr: &str) -> Option<(&'static str, Option<&'static str>)> { pub fn attrbute_to_static_str(attr: &str) -> Option<(&'static str, Option<&'static str>)> {
NO_NAMESPACE_ATTRIBUTES NO_NAMESPACE_ATTRIBUTES
.iter() .iter()
@@ -4,7 +4,6 @@ use dioxus_rsx::{
}; };
use quote::{quote, ToTokens, TokenStreamExt}; use quote::{quote, ToTokens, TokenStreamExt};
use syn::{Expr, Ident, Result}; use syn::{Expr, Ident, Result};
#[derive(Default)] #[derive(Default)]
pub struct CapturedContextBuilder { pub struct CapturedContextBuilder {
pub ifmted: Vec<IfmtInput>, pub ifmted: Vec<IfmtInput>,
@@ -146,7 +145,7 @@ impl ToTokens for CapturedContextBuilder {
pub struct CapturedContext<'a> { pub struct CapturedContext<'a> {
// map of the variable name to the formated value // map of the variable name to the formated value
pub captured: IfmtArgs, pub captured: IfmtArgs,
// // map of the attribute name and element path to the formated value // map of the attribute name and element path to the formated value
// pub captured_attribute_values: IfmtArgs, // pub captured_attribute_values: IfmtArgs,
// the only thing we can update in component is the children // the only thing we can update in component is the children
pub components: Vec<(&'static str, VNode<'a>)>, pub components: Vec<(&'static str, VNode<'a>)>,
@@ -159,10 +158,11 @@ pub struct CapturedContext<'a> {
} }
pub struct IfmtArgs { pub struct IfmtArgs {
// map expressions to the value string they produced // All expressions that have been resolved
pub named_args: Vec<FormattedArg>, pub named_args: Vec<FormattedArg>,
} }
/// A formated segment that has been resolved
pub struct FormattedArg { pub struct FormattedArg {
pub expr: &'static str, pub expr: &'static str,
pub format_args: &'static str, pub format_args: &'static str,
+1 -1
View File
@@ -1,4 +1,4 @@
// find the mapped attribute name // map the rsx name of the element to the html name of the element and the namespace that contains it
pub fn element_to_static_str(element: &str) -> Option<(&'static str, Option<&'static str>)> { pub fn element_to_static_str(element: &str) -> Option<(&'static str, Option<&'static str>)> {
ELEMENTS_WITH_MAPPED_ATTRIBUTES ELEMENTS_WITH_MAPPED_ATTRIBUTES
.iter() .iter()
+1
View File
@@ -1,5 +1,6 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// An error produced when interperting the rsx
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
ParseError(syn::Error), ParseError(syn::Error),
+39 -50
View File
@@ -8,43 +8,39 @@ use crate::captuered_context::{CapturedContext, IfmtArgs};
use crate::elements::element_to_static_str; use crate::elements::element_to_static_str;
use crate::error::{Error, RecompileReason}; use crate::error::{Error, RecompileReason};
struct InterpertedIfmt(IfmtInput); fn resolve_ifmt(ifmt: &IfmtInput, captured: &IfmtArgs) -> Result<String, Error> {
let mut result = String::new();
impl InterpertedIfmt { for seg in &ifmt.segments {
fn resolve(&self, captured: &IfmtArgs) -> Result<String, Error> { match seg {
let mut result = String::new(); Segment::Formatted {
for seg in &self.0.segments { segment,
match seg { format_args,
Segment::Formatted { } => {
segment, let expr = segment.to_token_stream();
format_args, let expr: Expr = parse2(expr).unwrap();
} => { let search = captured.named_args.iter().find(|fmted| {
let expr = segment.to_token_stream(); parse_str::<Expr>(fmted.expr).unwrap() == expr
let expr: Expr = parse2(expr).unwrap(); && fmted.format_args == format_args
let search = captured.named_args.iter().find(|fmted| { });
parse_str::<Expr>(fmted.expr).unwrap() == expr match search {
&& fmted.format_args == format_args Some(formatted) => {
}); result.push_str(&formatted.result);
match search { }
Some(formatted) => { None => {
result.push_str(&formatted.result); let expr_str = segment.to_token_stream().to_string();
} return Err(Error::RecompileRequiredError(
None => { RecompileReason::CapturedExpression(format!(
let expr_str = segment.to_token_stream().to_string(); "could not resolve {{{}:{}}}",
return Err(Error::RecompileRequiredError( expr_str, format_args
RecompileReason::CapturedExpression(format!( )),
"could not resolve {{{}:{}}}", ));
expr_str, format_args
)),
));
}
} }
} }
Segment::Literal(lit) => result.push_str(lit),
} }
Segment::Literal(lit) => result.push_str(lit),
} }
Ok(result)
} }
Ok(result)
} }
pub fn build<'a>( pub fn build<'a>(
@@ -67,10 +63,8 @@ fn build_node<'a>(
let bump = factory.bump(); let bump = factory.bump();
match node { match node {
BodyNode::Text(text) => { BodyNode::Text(text) => {
let ifmt = InterpertedIfmt( let ifmt = IfmtInput::from_str(&text.value()).map_err(|err| Error::ParseError(err))?;
IfmtInput::from_str(&text.value()).map_err(|err| Error::ParseError(err))?, let text = bump.alloc(resolve_ifmt(&ifmt, &ctx.captured)?);
);
let text = bump.alloc(ifmt.resolve(&ctx.captured)?);
Ok(factory.text(format_args!("{}", text))) Ok(factory.text(format_args!("{}", text)))
} }
BodyNode::Element(el) => { BodyNode::Element(el) => {
@@ -78,26 +72,22 @@ fn build_node<'a>(
for attr in &el.attributes { for attr in &el.attributes {
match &attr.attr { match &attr.attr {
ElementAttr::AttrText { .. } | ElementAttr::CustomAttrText { .. } => { ElementAttr::AttrText { .. } | ElementAttr::CustomAttrText { .. } => {
let (name, value): (String, InterpertedIfmt) = match &attr.attr { let (name, value): (String, IfmtInput) = match &attr.attr {
ElementAttr::AttrText { name, value } => ( ElementAttr::AttrText { name, value } => (
name.to_string(), name.to_string(),
InterpertedIfmt( IfmtInput::from_str(&value.value())
IfmtInput::from_str(&value.value()) .map_err(|err| Error::ParseError(err))?,
.map_err(|err| Error::ParseError(err))?,
),
), ),
ElementAttr::CustomAttrText { name, value } => ( ElementAttr::CustomAttrText { name, value } => (
name.value(), name.value(),
InterpertedIfmt( IfmtInput::from_str(&value.value())
IfmtInput::from_str(&value.value()) .map_err(|err| Error::ParseError(err))?,
.map_err(|err| Error::ParseError(err))?,
),
), ),
_ => unreachable!(), _ => unreachable!(),
}; };
if let Some((name, namespace)) = attrbute_to_static_str(&name) { if let Some((name, namespace)) = attrbute_to_static_str(&name) {
let value = bump.alloc(value.resolve(&ctx.captured)?); let value = bump.alloc(resolve_ifmt(&value, &ctx.captured)?);
attributes.push(Attribute { attributes.push(Attribute {
name, name,
value: AttributeValue::Text(value), value: AttributeValue::Text(value),
@@ -188,10 +178,9 @@ fn build_node<'a>(
None, None,
)), )),
Some(lit) => { Some(lit) => {
let ifmt: InterpertedIfmt = InterpertedIfmt( let ifmt: IfmtInput =
parse_str(&lit.value()).map_err(|err| Error::ParseError(err))?, parse_str(&lit.value()).map_err(|err| Error::ParseError(err))?;
); let key = bump.alloc(resolve_ifmt(&ifmt, &ctx.captured)?);
let key = bump.alloc(ifmt.resolve(&ctx.captured)?);
Ok(factory.raw_element( Ok(factory.raw_element(
tag, tag,
+13 -3
View File
@@ -22,6 +22,7 @@ lazy_static! {
pub static ref RSX_CONTEXT: RsxContext = RsxContext::new(RsxData::default()); pub static ref RSX_CONTEXT: RsxContext = RsxContext::new(RsxData::default());
} }
// the location of the code relative to the current crate based on [std::panic::Location]
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub struct CodeLocation { pub struct CodeLocation {
pub file: String, pub file: String,
@@ -29,6 +30,7 @@ pub struct CodeLocation {
pub column: u32, pub column: u32,
} }
/// Get the resolved rsx given the origional rsx, a captured context of dynamic components, and a factory to build the resulting node
pub fn resolve_scope<'a>( pub fn resolve_scope<'a>(
location: CodeLocation, location: CodeLocation,
rsx: &'static str, rsx: &'static str,
@@ -57,7 +59,7 @@ pub fn resolve_scope<'a>(
} }
} }
pub fn interpert_rsx<'a, 'b>( fn interpert_rsx<'a, 'b>(
factory: dioxus_core::NodeFactory<'a>, factory: dioxus_core::NodeFactory<'a>,
text: &str, text: &str,
context: captuered_context::CapturedContext<'a>, context: captuered_context::CapturedContext<'a>,
@@ -69,6 +71,7 @@ pub fn interpert_rsx<'a, 'b>(
) )
} }
/// get the code location of the code that called this function
#[track_caller] #[track_caller]
pub fn get_line_num() -> CodeLocation { pub fn get_line_num() -> CodeLocation {
let location = Location::caller(); let location = Location::caller();
@@ -79,11 +82,13 @@ pub fn get_line_num() -> CodeLocation {
} }
} }
/// A handle to the rsx context with interior mutability
#[derive(Debug)] #[derive(Debug)]
pub struct RsxContext { pub struct RsxContext {
data: RwLock<RsxData>, data: RwLock<RsxData>,
} }
/// A store of the text for the rsx macro for each call to rsx
#[derive(Default)] #[derive(Default)]
pub struct RsxData { pub struct RsxData {
pub hm: HashMap<CodeLocation, String>, pub hm: HashMap<CodeLocation, String>,
@@ -104,6 +109,7 @@ impl RsxContext {
} }
} }
/// Set the text for an rsx call at some location
pub fn insert(&self, loc: CodeLocation, text: String) { pub fn insert(&self, loc: CodeLocation, text: String) {
let mut write = self.data.write().unwrap(); let mut write = self.data.write().unwrap();
write.hm.insert(loc, text); write.hm.insert(loc, text);
@@ -112,25 +118,29 @@ impl RsxContext {
} }
} }
pub fn read(&self) -> RwLockReadGuard<RsxData> { fn read(&self) -> RwLockReadGuard<RsxData> {
self.data.read().unwrap() self.data.read().unwrap()
} }
pub fn report_error(&self, error: Error) { fn report_error(&self, error: Error) {
if let Some(handler) = &self.data.write().unwrap().error_handler { if let Some(handler) = &self.data.write().unwrap().error_handler {
handler.handle_error(error) handler.handle_error(error)
} }
} }
/// Set the handler for errors interperting the rsx
pub fn set_error_handler(&self, handler: impl ErrorHandler + 'static) { pub fn set_error_handler(&self, handler: impl ErrorHandler + 'static) {
self.data.write().unwrap().error_handler = Some(Box::new(handler)); self.data.write().unwrap().error_handler = Some(Box::new(handler));
} }
/// Provide the scduler channel from [dioxus_code::VirtualDom::get_scheduler_channel].
/// The channel allows the interpreter to force re-rendering of the dom when the rsx is changed.
pub fn provide_scheduler_channel(&self, channel: UnboundedSender<SchedulerMsg>) { pub fn provide_scheduler_channel(&self, channel: UnboundedSender<SchedulerMsg>) {
self.data.write().unwrap().scheduler_channel = Some(channel) self.data.write().unwrap().scheduler_channel = Some(channel)
} }
} }
/// A error handler for errors reported by the rsx interperter
pub trait ErrorHandler: Send + Sync { pub trait ErrorHandler: Send + Sync {
fn handle_error(&self, err: Error); fn handle_error(&self, err: Error);
} }
+1 -1
View File
@@ -65,6 +65,6 @@ pub mod prelude {
#[cfg(feature = "hot_reload")] #[cfg(feature = "hot_reload")]
pub use dioxus_rsx_interpreter::{ pub use dioxus_rsx_interpreter::{
captuered_context::{CapturedContext, FormattedArg, IfmtArgs}, captuered_context::{CapturedContext, FormattedArg, IfmtArgs},
get_line_num, interpert_rsx, resolve_scope, CodeLocation, RsxContext, get_line_num, resolve_scope, CodeLocation, RsxContext,
}; };
} }