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 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 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 {
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("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 peek_tail <'a> (head: DslPerhaps<&'a str>) -> impl Fn(&'a str)->DslPerhaps<&'a str> {
move|src|match head {