diff --git a/dsl/src/dsl.rs b/dsl/src/dsl.rs index e9d108b..cb2ee5c 100644 --- a/dsl/src/dsl.rs +++ b/dsl/src/dsl.rs @@ -81,7 +81,7 @@ pub const fn peek_tail (src: &str) -> DslPerhaps<&str> { Ok(None) => Ok(None), Ok(Some((start, length))) => { let tail = str_range(src, start + length, src.len()); - for_each!((i, c) in char_indices(tail) => if !is_space(c) { return Ok(Some(tail)) }); + for_each!((_i, c) in char_indices(tail) => if !is_space(c) { return Ok(Some(tail)) }); Ok(None) }, } diff --git a/dsl/src/dsl_conv.rs b/dsl/src/dsl_conv.rs index ae214dd..033e6eb 100644 --- a/dsl/src/dsl_conv.rs +++ b/dsl/src/dsl_conv.rs @@ -1,5 +1,43 @@ use crate::*; +/// Namespace. Currently linearly searched. +pub struct DslNs<'t, T: 't>(pub &'t [(&'t str, T)]); + +/// Namespace where keys are symbols. +pub trait DslSymNs<'t, T: 't>: 't { + const SYMS: DslNs<'t, fn (&'t Self)->T>; + fn from_sym (&'t self, dsl: D) -> Usually { + if let Some(dsl) = dsl.sym()? { + for (sym, get) in Self::SYMS.0 { + if dsl == *sym { + return Ok(get(self)) + } + } + } + return Err(format!("not found: sym: {dsl:?}").into()) + } +} + +#[macro_export] macro_rules! dsl_sym ( + (|$state:ident:$State:ty| -> $type:ty {$($lit:literal => $exp:expr),* $(,)?})=>{ + impl<'t> DslSymNs<'t, $type> for $State { + const SYMS: DslNs<'t, fn (&'t $State)->$type> = + DslNs(&[$(($lit, |$state: &$State|$exp)),*]); } }); + +pub trait DslExpNs<'t, T: 't>: 't { + const EXPS: DslNs<'t, fn (&'t Self, &str)->T>; +} + +#[macro_export] macro_rules! dsl_exp ( + (|$state:ident:$State:ty|->$type:ty { $( + [$key:literal $(/ $sub:ident: $Sub:ty)? $(, $arg:ident $(?)? :$argtype:ty)*] => $body:expr + ),* $(,)? }) => { + impl<'t> DslExpNs<'t, $type> for $State { + const EXPS: DslNs<'t, fn (&'t $State, &str)->$type> = + DslNs(&[]); } }); + +// TODO DEPRECATE: + /// `T` + [Dsl] -> `Self`. pub trait FromDsl: Sized { fn from_dsl (state: &T, dsl: &impl Dsl) -> Perhaps; diff --git a/input/src/input_dsl.rs b/input/src/input_dsl.rs index cc54282..f4cd98f 100644 --- a/input/src/input_dsl.rs +++ b/input/src/input_dsl.rs @@ -62,7 +62,7 @@ impl EventMap { /// Create event map from path to text file. pub fn load_from_path <'s> ( &'s mut self, path: impl AsRef - ) -> Usually<&mut Self> where Self: DslInto + DslInto { + ) -> Usually<&'s mut Self> where Self: DslInto + DslInto { if exists(path.as_ref())? { let source = read_to_string(&path)?; let path: Arc = Arc::new(path.as_ref().into()); @@ -81,7 +81,7 @@ impl EventMap { /// Load one event binding into the event map. pub fn load_from_source_one <'s> ( &'s mut self, dsl: impl Dsl, path: &Option<&Arc> - ) -> Usually<&mut Self> where Self: DslInto + DslInto { + ) -> Usually<&'s mut Self> where Self: DslInto + DslInto { if let Some(exp) = dsl.head()?.exp()? && let Some(sym) = exp.head()?.sym()? && let Some(tail) = exp.tail()? @@ -117,10 +117,10 @@ impl EventMap { } impl Binding { pub fn from_dsl (dsl: impl Dsl) -> Usually { - let mut command: Option = None; - let mut condition: Option = None; - let mut description: Option> = None; - let mut source: Option> = None; + let command: Option = None; + let condition: Option = None; + let description: Option> = None; + let source: Option> = None; if let Some(command) = command { Ok(Self { command, condition, description, source }) } else { diff --git a/output/src/ops.rs b/output/src/ops.rs index bdbcff0..f16d971 100644 --- a/output/src/ops.rs +++ b/output/src/ops.rs @@ -776,22 +776,16 @@ pub struct Stack { direction: Direction, callback: F } -impl Stack { +impl)->())->()> Stack { + pub fn north (callback: F) -> Self { Self::new(North, callback) } + pub fn south (callback: F) -> Self { Self::new(South, callback) } + pub fn east (callback: F) -> Self { Self::new(East, callback) } + pub fn west (callback: F) -> Self { Self::new(West, callback) } + pub fn above (callback: F) -> Self { Self::new(Above, callback) } + pub fn below (callback: F) -> Self { Self::new(Below, callback) } pub fn new (direction: Direction, callback: F) -> Self { Self { direction, callback, __: Default::default(), } } - pub fn north (callback: F) -> Self { - Self::new(North, callback) - } - pub fn south (callback: F) -> Self { - Self::new(South, callback) - } - pub fn east (callback: F) -> Self { - Self::new(East, callback) - } - pub fn west (callback: F) -> Self { - Self::new(West, callback) - } } impl)->())->()> Content for Stack { fn layout (&self, to: E::Area) -> E::Area { @@ -802,32 +796,22 @@ impl)->())->()> Content for St (self.callback)(&mut move |component: &dyn Render|{ let [_, _, w, h] = component.layout([x, y, w_remaining, h_remaining].into()).xywh(); match self.direction { - South => { - y = y.plus(h); - h_used = h_used.plus(h); - h_remaining = h_remaining.minus(h); - w_used = w_used.max(w); - }, - East => { - x = x.plus(w); - w_used = w_used.plus(w); - w_remaining = w_remaining.minus(w); - h_used = h_used.max(h); - }, - North | West => { - todo!() - }, - _ => unreachable!(), + North | West => { todo!() }, + Above | Below => {}, + South => { y = y.plus(h); + h_used = h_used.plus(h); + h_remaining = h_remaining.minus(h); + w_used = w_used.max(w); }, + East => { x = x.plus(w); + w_used = w_used.plus(w); + w_remaining = w_remaining.minus(w); + h_used = h_used.max(h); }, } }); match self.direction { - North | West => { - todo!() - }, - South | East => { - [to.x(), to.y(), w_used.into(), h_used.into()].into() - }, - _ => unreachable!(), + North | West => { todo!() }, + South | East => { [to.x(), to.y(), w_used.into(), h_used.into()].into() }, + Above | Below => { [to.x(), to.y(), to.w(), to.h()].into() }, } } fn render (&self, to: &mut E) { @@ -838,22 +822,16 @@ impl)->())->()> Content for St (self.callback)(&mut move |component: &dyn Render|{ let layout = component.layout([x, y, w_remaining, h_remaining].into()); match self.direction { - South => { - y = y.plus(layout.h()); - h_remaining = h_remaining.minus(layout.h()); - h_used = h_used.plus(layout.h()); - to.place(layout, component); - }, - East => { - x = x.plus(layout.w()); - w_remaining = w_remaining.minus(layout.w()); - w_used = w_used.plus(layout.h()); - to.place(layout, component); - }, - North | West => { - todo!() - }, - _ => unreachable!() + Above | Below => { to.place(layout, component); } + North | West => { todo!() }, + South => { y = y.plus(layout.h()); + h_remaining = h_remaining.minus(layout.h()); + h_used = h_used.plus(layout.h()); + to.place(layout, component); }, + East => { x = x.plus(layout.w()); + w_remaining = w_remaining.minus(layout.w()); + w_used = w_used.plus(layout.h()); + to.place(layout, component); }, } }); }