diff --git a/dsl/src/dsl_conv.rs b/dsl/src/dsl_conv.rs index 3d125a4..033e6eb 100644 --- a/dsl/src/dsl_conv.rs +++ b/dsl/src/dsl_conv.rs @@ -6,15 +6,15 @@ 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) -> Perhaps { + 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(Some(get(self))) + return Ok(get(self)) } } } - return Ok(None) + return Err(format!("not found: sym: {dsl:?}").into()) } } @@ -26,21 +26,11 @@ pub trait DslSymNs<'t, T: 't>: 't { pub trait DslExpNs<'t, T: 't>: 't { const EXPS: DslNs<'t, fn (&'t Self, &str)->T>; - fn from_exp (&'t self, dsl: D) -> Perhaps { - if let Some(exp) = dsl.exp()? { - for (key, value) in Self::EXPS.0.iter() { - if exp.head() == Ok(Some(key)) { - return Ok(Some(value(self, exp.tail()?.unwrap_or("")))) - } - } - } - return Ok(None) - } } #[macro_export] macro_rules! dsl_exp ( - (|$state:ident:$State:ty$(, $tail:ident)?|->$type:ty { $( - ($key:literal $(/ $sub:ident: $Sub:ty)? $(, $arg:ident $(?)? :$argtype:ty)*) => $body:expr + (|$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> = diff --git a/tui/src/tui_content/tui_string.rs b/tui/src/tui_content/tui_string.rs index 57ae7f4..92b91fc 100644 --- a/tui/src/tui_content/tui_string.rs +++ b/tui/src/tui_content/tui_string.rs @@ -3,37 +3,22 @@ use crate::ratatui::prelude::Position; use unicode_width::{UnicodeWidthStr, UnicodeWidthChar}; impl_content_layout_render!(TuiOut: |self: &str, to| - layout = to.center_xy([width_chars_max(to.w(), self), 1]); - render = {let [x, y, w, ..] = Content::layout(self, to.area()); - to.text(self, x, y, w)}); - + layout = to.center_xy([self.chars().count() as u16, 1]); + render = {let [x, y, ..] = Content::layout(self, to.area()); + to.blit(self, x, y, None)}); impl_content_layout_render!(TuiOut: |self: String, to| - layout = Content::::layout(&self.as_str(), to); - render = Content::::render(&self.as_str(), to)); - -impl_content_layout_render!(TuiOut: |self: Arc, to| - layout = Content::::layout(&self.as_ref(), to); - render = Content::::render(&self.as_ref(), to)); - + layout = to.center_xy([self.chars().count() as u16, 1]); + render = {let [x, y, ..] = Content::layout(self, to.area()); + to.blit(self, x, y, None)}); impl_content_layout_render!(TuiOut: |self: std::sync::RwLock, to| layout = Content::::layout(&self.read().unwrap(), to); render = Content::::render(&self.read().unwrap(), to)); - impl_content_layout_render!(TuiOut: |self: std::sync::RwLockReadGuard<'_, String>, to| layout = Content::::layout(&**self, to); render = Content::::render(&**self, to)); - -fn width_chars_max (max: u16, text: impl AsRef) -> u16 { - let mut width: u16 = 0; - let mut chars = text.as_ref().chars(); - while let Some(c) = chars.next() { - width += c.width().unwrap_or(0) as u16; - if width > max { - break - } - } - return width -} +impl_content_layout_render!(TuiOut: |self: Arc, to| + layout = to.center_xy([self.chars().count() as u16, 1]); + render = to.blit(self, to.area.x(), to.area.y(), None)); /// Trim string with [unicode_width]. pub fn trim_string (max_width: usize, input: impl AsRef) -> String { diff --git a/tui/src/tui_engine/tui_output.rs b/tui/src/tui_engine/tui_output.rs index 9b35936..04cbe94 100644 --- a/tui/src/tui_engine/tui_output.rs +++ b/tui/src/tui_engine/tui_output.rs @@ -1,7 +1,6 @@ use crate::*; use std::time::Duration; use std::thread::{spawn, JoinHandle}; -use unicode_width::*; #[derive(Default)] pub struct TuiOut { pub buffer: Buffer, @@ -11,12 +10,8 @@ impl Output for TuiOut { type Unit = u16; type Size = [Self::Unit;2]; type Area = [Self::Unit;4]; - #[inline] fn area (&self) -> [u16;4] { - self.area - } - #[inline] fn area_mut (&mut self) -> &mut [u16;4] { - &mut self.area - } + #[inline] fn area (&self) -> [u16;4] { self.area } + #[inline] fn area_mut (&mut self) -> &mut [u16;4] { &mut self.area } #[inline] fn place <'t, T: Render + ?Sized> (&mut self, area: [u16;4], content: &'t T) { let last = self.area(); *self.area_mut() = area; @@ -68,32 +63,10 @@ impl TuiOut { pub fn blit ( &mut self, text: &impl AsRef, x: u16, y: u16, style: Option