diff --git a/dsl/src/dsl_provide.rs b/dsl/src/dsl_provide.rs index cf61968..f98130b 100644 --- a/dsl/src/dsl_provide.rs +++ b/dsl/src/dsl_provide.rs @@ -16,19 +16,35 @@ use crate::*; /// Maps a sequencer of EDN tokens to parameters of supported types /// for a given context. -pub trait Dsl: Sized { - fn take <'state, 'source> ( - &'state self, - _: &mut TokenIter<'source> - ) -> Perhaps { +pub trait Dsl: Sized { + fn take <'state, 'source> (&'state self, _: &mut TokenIter<'source>) -> Perhaps { unimplemented!() } fn take_or_fail <'state, 'source> ( &'state self, token: &mut TokenIter<'source>, error: impl Into> - ) -> Usually { - if let Some(value) = Dsl::::take(self, token)? { + ) -> Usually { + if let Some(value) = Dsl::::take(self, token)? { + Ok(value) + } else { + Result::Err(error.into()) + } + } +} + +pub trait FromDsl<'state, State>: Sized { + fn take_from <'source: 'state> (state: &'state State, _token: &mut TokenIter<'source>) + -> Perhaps + { + unimplemented!() + } + fn take_from_or_fail <'source: 'state> ( + state: &'state State, + token: &mut TokenIter<'source>, + error: impl Into> + ) -> Usually { + if let Some(value) = FromDsl::::take_from(state, token)? { Ok(value) } else { Result::Err(error.into()) @@ -53,23 +69,3 @@ impl<'state, X, Y> Dsl for Y where Y: FromDsl<'state, X> { //impl> Dsl for T { //} - -pub trait FromDsl<'state, T>: Sized { - fn take_from <'source: 'state> ( - state: &'state T, - _token: &mut TokenIter<'source> - ) -> Perhaps { - unimplemented!() - } - fn take_from_or_fail <'source: 'state> ( - state: &'state T, - token: &mut TokenIter<'source>, - error: impl Into> - ) -> Usually { - if let Some(value) = FromDsl::::take_from(state, token)? { - Ok(value) - } else { - Result::Err(error.into()) - } - } -} diff --git a/output/src/space/measure.rs b/output/src/space/measure.rs index a894b60..9ed5c2c 100644 --- a/output/src/space/measure.rs +++ b/output/src/space/measure.rs @@ -85,7 +85,7 @@ impl Measure { pub fn format (&self) -> Arc { format!("{}x{}", self.w(), self.h()).into() } - pub fn of > (&self, item: T) -> Bsp, T> { + pub fn of > (&self, item: T) -> Bsp, T> { Bsp::b(Fill::xy(self), item) } } diff --git a/output/src/view.rs b/output/src/view.rs index 85fac4b..8f40cc2 100644 --- a/output/src/view.rs +++ b/output/src/view.rs @@ -1,47 +1,12 @@ use crate::*; -#[macro_export] macro_rules! view { - ($Output:ty: |$self:ident: $State:ty| $expr:expr; { - $($sym:literal => $body:expr),* $(,)? - }) => { - impl Content<$Output> for $State { - fn content (&$self) -> impl Render<$Output> { $expr } - } - impl<'a> ViewContext<'a, $Output> for $State { - fn get_content_sym (&'a $self, iter: &Value<'a>) -> Perhaps> { - Ok(if let Value::Sym(s) = value { - match *s { - $($sym => Some($body.boxed()),)* - _ => None - } - } else { - return Err(format!("expected content, got: {iter:?}").into()) - }) - } - } - } -} - -// An ephemeral wrapper around view state and view description, -// that is meant to be constructed and returned from [Content::content]. #[cfg(feature = "dsl")] -pub struct View<'a, T>( - pub &'a T, - pub TokenIter<'a> -); - -#[cfg(feature = "dsl")] -impl<'a, O: Output + 'a, T: ViewContext<'a, O>> Content for View<'a, T> { - fn content (&self) -> impl Render { - let mut iter = self.1.clone(); - while let Some(Token { value, .. }) = iter.peek() { - if let Ok(Some(content)) = self.0.get_content(&mut iter) { - return Some(content) - // TODO handle errors here, how? - // error receiver trait in viewcontext? - } +#[macro_export] macro_rules! try_delegate { + ($s:ident, $dsl:expr, $T:ty) => { + let value: Option<$T> = FromDsl::take_from($s, $dsl)?; + if let Some(value) = value { + return Ok(Some(value.boxed())) } - return None } } @@ -96,13 +61,3 @@ pub trait ViewContext<'state, E: Output + 'state>: Send + Sync Ok(None) } } - -#[cfg(feature = "dsl")] -#[macro_export] macro_rules! try_delegate { - ($s:ident, $dsl:expr, $T:ty) => { - let value: Option<$T> = FromDsl::take_from($s, $dsl)?; - if let Some(value) = value { - return Ok(Some(value.boxed())) - } - } -} diff --git a/proc/src/proc_view.rs b/proc/src/proc_view.rs index f1fb4e2..48af79f 100644 --- a/proc/src/proc_view.rs +++ b/proc/src/proc_view.rs @@ -44,7 +44,7 @@ impl Parse for ViewImpl { impl ToTokens for ViewDef { fn to_tokens (&self, out: &mut TokenStream2) { let Self(ViewMeta { output }, ViewImpl { block, exposed }) = self; - let ident = &block.self_ty; + let view = &block.self_ty; let mut available = vec![]; let exposed: Vec<_> = exposed.iter().map(|(k,v)|{ available.push(k.clone()); @@ -52,24 +52,24 @@ impl ToTokens for ViewDef { }).collect(); let available: String = available.join(", "); let error_msg = LitStr::new( - &format!("expected Sym(content), got: {{iter:?}}, available: {available}"), + &format!("expected Sym(content), got: {{token:?}}, available: {available}"), Span::call_site() ); for token in quote! { #block /// Generated by [tengri_proc]. - impl ::tengri::output::Content<#output> for #ident { + impl ::tengri::output::Content<#output> for #view { fn content (&self) -> impl Render<#output> { - // TODO move to self.view() - self.size.of(::tengri::output::View(self, self.config.view)) + self.view() } } /// Generated by [tengri_proc]. - impl<'state> ::tengri::output::ViewContext<'state, #output> for #ident { - fn get_content_sym <'source: 'state> (&'state self, iter: &mut TokenIter<'source>) - -> ::tengri::Perhaps> - { - Ok(match iter.peek() { #(#exposed)* _ => panic!(#error_msg) }) + impl<'state> ::tengri::dsl::FromDsl<'state, #view> for ::tengri::output::RenderBox<'state, #output> { + fn take_from <'source: 'state> ( + state: &'state #view, + token: &mut ::tengri::dsl::TokenIter<'source> + ) -> Perhaps { + Ok(match token.peek() { #(#exposed)* _ => None }) } } } { @@ -126,7 +126,7 @@ impl ToTokens for ViewArm { out.append(Ident::new("Some", Span::call_site())); out.append(Group::new(Delimiter::Parenthesis, { let mut out = TokenStream2::new(); - out.append(Ident::new("self", Span::call_site())); + out.append(Ident::new("state", Span::call_site())); out.append(Punct::new('.', Alone)); out.append(value.clone()); out.append(Group::new(Delimiter::Parenthesis, TokenStream2::new())); diff --git a/tui/src/tui_content.rs b/tui/src/tui_content.rs index 38960b9..0d563fd 100644 --- a/tui/src/tui_content.rs +++ b/tui/src/tui_content.rs @@ -21,6 +21,30 @@ impl> Content for std::sync::Arc { } } +impl> Content for Result> { + fn content (&self) -> impl Render { + Bsp::a(self.as_ref().ok(), self.as_ref().err() + .map(|e|Tui::fg_bg(Color::Rgb(255,255,255), Color::Rgb(32,32,32), e.to_string()))) + } +} + +//impl> Render for Result> { + //fn layout (&self, to: [u16;4]) -> [u16;4] { + //match self { + //Ok(content) => content.layout(to), + //Err(e) => [0, 0, to.w(), to.h()] + //} + //} + //fn render (&self, to: &mut TuiOut) { + //match self { + //Ok(content) => content.render(to), + //Err(e) => to.blit(&e.to_string(), 0, 0, Some(Style::default() + //.bg(Color::Rgb(32,32,32)) + //.fg(Color::Rgb(255,255,255)))) + //} + //} +//} + mod tui_border; pub use self::tui_border::*; mod tui_button; pub use self::tui_button::*; mod tui_color; pub use self::tui_color::*;