dsl: macro dsl_for_each -> method each

This commit is contained in:
🪞👃🪞 2025-08-03 19:36:01 +03:00
parent a601d3d806
commit 9ccd7e5c69
2 changed files with 8 additions and 18 deletions

View file

@ -28,6 +28,14 @@ impl<D: Dsl> DslExp for D {} pub trait DslExp: Dsl {
fn exp (&self) -> DslPerhaps<&str> {ok_flat(self.src()?.map(exp_peek_inner_only))} fn exp (&self) -> DslPerhaps<&str> {ok_flat(self.src()?.map(exp_peek_inner_only))}
fn head (&self) -> DslPerhaps<&str> {ok_flat(self.src()?.map(peek))} fn head (&self) -> DslPerhaps<&str> {ok_flat(self.src()?.map(peek))}
fn tail (&self) -> DslPerhaps<&str> {ok_flat(self.src()?.map(peek_tail(self.head())))} fn tail (&self) -> DslPerhaps<&str> {ok_flat(self.src()?.map(peek_tail(self.head())))}
fn each (&self, mut cb: impl FnMut(&str)->Usually<()>) -> Usually<()> {
Ok(if let Some(head) = self.head()? {
cb(head)?;
if let Some(tail) = self.tail()? {
tail.each(cb)?;
}
})
}
} }
impl<D: Dsl> DslText for D {} pub trait DslText: Dsl { impl<D: Dsl> DslText for D {} pub trait DslText: Dsl {
fn text (&self) -> DslPerhaps<&str> {ok_flat(self.src()?.map(text_peek_only))} fn text (&self) -> DslPerhaps<&str> {ok_flat(self.src()?.map(text_peek_only))}
@ -55,20 +63,6 @@ pub enum DslError {
#[error("parse failed: error #{0}")] Code(u8), #[error("parse failed: error #{0}")] Code(u8),
#[error("end reached")] End #[error("end reached")] End
} }
#[macro_export] macro_rules! dsl_for_each (($dsl:expr => |$next:ident|$body:expr)=>{
let mut dsl: Arc<str> = $dsl.src().into();
let mut $next: Option<Arc<str>> = dsl.next()?.map(Into::into);
let mut rest: Option<Arc<str>> = dsl.rest()?.map(Into::into);
loop {
if let Some($next) = $next { $body } else { break };
if let Some(next) = rest {
$next = next.next()?.map(Into::into);
rest = next.rest()?.map(Into::into);
} else {
break
}
}
});
fn ok_flat <T> (x: Option<DslPerhaps<T>>) -> DslPerhaps<T> { Ok(x.transpose()?.flatten()) } fn ok_flat <T> (x: Option<DslPerhaps<T>>) -> DslPerhaps<T> { Ok(x.transpose()?.flatten()) }
fn peek_tail <'a> (head: DslPerhaps<&'a str>) -> impl Fn(&'a str)->DslPerhaps<&'a str> { fn peek_tail <'a> (head: DslPerhaps<&'a str>) -> impl Fn(&'a str)->DslPerhaps<&'a str> {
move|src|match head { move|src|match head {

View file

@ -1,5 +1,4 @@
use crate::*; use crate::*;
/// Event source /// Event source
pub trait Input: Sized { pub trait Input: Sized {
/// Type of input event /// Type of input event
@ -13,13 +12,11 @@ pub trait Input: Sized {
/// Mark component as done /// Mark component as done
fn done (&self); fn done (&self);
} }
flex_trait_mut!(Handle <E: Input> { flex_trait_mut!(Handle <E: Input> {
fn handle (&mut self, _input: &E) -> Perhaps<E::Handled> { fn handle (&mut self, _input: &E) -> Perhaps<E::Handled> {
Ok(None) Ok(None)
} }
}); });
pub trait Command<S>: Send + Sync + Sized { pub trait Command<S>: Send + Sync + Sized {
fn execute (self, state: &mut S) -> Perhaps<Self>; fn execute (self, state: &mut S) -> Perhaps<Self>;
fn delegate <T> (self, state: &mut S, wrap: impl Fn(Self)->T) -> Perhaps<T> fn delegate <T> (self, state: &mut S, wrap: impl Fn(Self)->T) -> Perhaps<T>
@ -28,7 +25,6 @@ pub trait Command<S>: Send + Sync + Sized {
Ok(self.execute(state)?.map(wrap)) Ok(self.execute(state)?.map(wrap))
} }
} }
impl<S, T: Command<S>> Command<S> for Option<T> { impl<S, T: Command<S>> Command<S> for Option<T> {
fn execute (self, _: &mut S) -> Perhaps<Self> { fn execute (self, _: &mut S) -> Perhaps<Self> {
Ok(None) Ok(None)