Checkpoint

This commit is contained in:
Antonio Scandurra 2023-10-20 12:12:06 +02:00
parent ac181183cc
commit c1f7c9bb87
2 changed files with 18 additions and 11 deletions

View file

@ -38,14 +38,14 @@ impl DispatchContext {
let key = source let key = source
.chars() .chars()
.take_while(|ch| ch.is_alphanumeric()) .take_while(|c| is_identifier_char(*c))
.collect::<String>(); .collect::<String>();
source = skip_whitespace(&source[key.len()..]); source = skip_whitespace(&source[key.len()..]);
if let Some(suffix) = source.strip_prefix('=') { if let Some(suffix) = source.strip_prefix('=') {
source = skip_whitespace(suffix); source = skip_whitespace(suffix);
let value = source let value = source
.chars() .chars()
.take_while(|ch| ch.is_alphanumeric()) .take_while(|c| is_identifier_char(*c))
.collect::<String>(); .collect::<String>();
source = skip_whitespace(&source[value.len()..]); source = skip_whitespace(&source[value.len()..]);
context.set(key, value); context.set(key, value);
@ -106,7 +106,7 @@ impl DispatchContextPredicate {
} }
pub fn eval(&self, contexts: &[&DispatchContext]) -> bool { pub fn eval(&self, contexts: &[&DispatchContext]) -> bool {
let Some(context) = contexts.first() else { let Some(context) = contexts.last() else {
return false; return false;
}; };
match self { match self {
@ -122,7 +122,9 @@ impl DispatchContextPredicate {
.map(|value| value != right) .map(|value| value != right)
.unwrap_or(true), .unwrap_or(true),
Self::Not(pred) => !pred.eval(contexts), Self::Not(pred) => !pred.eval(contexts),
Self::Child(parent, child) => parent.eval(&contexts[1..]) && child.eval(contexts), Self::Child(parent, child) => {
parent.eval(&contexts[..contexts.len() - 1]) && child.eval(contexts)
}
Self::And(left, right) => left.eval(contexts) && right.eval(contexts), Self::And(left, right) => left.eval(contexts) && right.eval(contexts),
Self::Or(left, right) => left.eval(contexts) || right.eval(contexts), Self::Or(left, right) => left.eval(contexts) || right.eval(contexts),
} }
@ -180,9 +182,9 @@ impl DispatchContextPredicate {
let (predicate, source) = Self::parse_expr(&source, PRECEDENCE_NOT)?; let (predicate, source) = Self::parse_expr(&source, PRECEDENCE_NOT)?;
Ok((DispatchContextPredicate::Not(Box::new(predicate)), source)) Ok((DispatchContextPredicate::Not(Box::new(predicate)), source))
} }
_ if next.is_alphanumeric() || next == '_' => { _ if is_identifier_char(next) => {
let len = source let len = source
.find(|c: char| !(c.is_alphanumeric() || c == '_')) .find(|c: char| !is_identifier_char(c))
.unwrap_or(source.len()); .unwrap_or(source.len());
let (identifier, rest) = source.split_at(len); let (identifier, rest) = source.split_at(len);
source = skip_whitespace(rest); source = skip_whitespace(rest);
@ -230,6 +232,10 @@ const PRECEDENCE_AND: u32 = 3;
const PRECEDENCE_EQ: u32 = 4; const PRECEDENCE_EQ: u32 = 4;
const PRECEDENCE_NOT: u32 = 5; const PRECEDENCE_NOT: u32 = 5;
fn is_identifier_char(c: char) -> bool {
c.is_alphanumeric() || c == '_' || c == '-'
}
fn skip_whitespace(source: &str) -> &str { fn skip_whitespace(source: &str) -> &str {
let len = source let len = source
.find(|c: char| !c.is_whitespace()) .find(|c: char| !c.is_whitespace())

View file

@ -81,6 +81,8 @@ impl FocusStory {
let child_2 = cx.focus_handle(); let child_2 = cx.focus_handle();
view(cx.entity(|cx| ()), move |_, cx| { view(cx.entity(|cx| ()), move |_, cx| {
div() div()
.id("parent")
.focusable(&parent)
.context("parent") .context("parent")
.on_action(|_, action: &ActionA, phase, cx| { .on_action(|_, action: &ActionA, phase, cx| {
println!("Action A dispatched on parent during {:?}", phase); println!("Action A dispatched on parent during {:?}", phase);
@ -88,7 +90,6 @@ impl FocusStory {
.on_action(|_, action: &ActionB, phase, cx| { .on_action(|_, action: &ActionB, phase, cx| {
println!("Action B dispatched on parent during {:?}", phase); println!("Action B dispatched on parent during {:?}", phase);
}) })
.focusable(&parent)
.on_focus(|_, _, _| println!("Parent focused")) .on_focus(|_, _, _| println!("Parent focused"))
.on_blur(|_, _, _| println!("Parent blurred")) .on_blur(|_, _, _| println!("Parent blurred"))
.on_focus_in(|_, _, _| println!("Parent focus_in")) .on_focus_in(|_, _, _| println!("Parent focus_in"))
@ -107,8 +108,8 @@ impl FocusStory {
div() div()
.id("child-1") .id("child-1")
.context("child-1") .context("child-1")
.on_action(|_, action: &ActionA, phase, cx| { .on_action(|_, action: &ActionB, phase, cx| {
println!("Action A dispatched on child 1 during {:?}", phase); println!("Action B dispatched on child 1 during {:?}", phase);
}) })
.focusable(&child_1) .focusable(&child_1)
.w_full() .w_full()
@ -132,8 +133,8 @@ impl FocusStory {
div() div()
.id("child-2") .id("child-2")
.context("child-2") .context("child-2")
.on_action(|_, action: &ActionB, phase, cx| { .on_action(|_, action: &ActionC, phase, cx| {
println!("Action B dispatched on child 2 during {:?}", phase); println!("Action C dispatched on child 2 during {:?}", phase);
}) })
.focusable(&child_2) .focusable(&child_2)
.w_full() .w_full()