mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
unify edn_view entrypoint
This commit is contained in:
parent
df50bb9f47
commit
9cd6e9f195
16 changed files with 603 additions and 541 deletions
|
|
@ -1,11 +1,42 @@
|
|||
use crate::*;
|
||||
use std::marker::PhantomData;
|
||||
use EdnItem::*;
|
||||
|
||||
#[macro_export] macro_rules! edn_view {
|
||||
($Output:ty: |$self:ident: $App:ty| $content:expr; {
|
||||
$( $type:ty { $($sym:literal => $value:expr),* } );*
|
||||
}) => {
|
||||
impl Content<$Output> for $App {
|
||||
fn content(&$self) -> impl Render<$Output> { $content }
|
||||
}
|
||||
$(
|
||||
impl<'a> EdnProvide<'a, $type> for $App {
|
||||
fn get <S: AsRef<str>> (&'a $self, edn: &'a EdnItem<S>) -> Option<$type> {
|
||||
Some(match edn.to_ref() {
|
||||
$(EdnItem::Sym($sym) => $value,)*
|
||||
_ => return None
|
||||
})
|
||||
}
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
/// Implements `EdnProvide` for content components and expressions
|
||||
#[macro_export] macro_rules! edn_provide_content {
|
||||
(|$self:ident:$Stat:ty|{ $($pat:pat => $expr:expr),* $(,)? }) => {
|
||||
impl<'a> EdnProvide<'a, Box<dyn Render<TuiOut> + 'a>> for $State {
|
||||
fn get <S: AsRef<str>> (&'a $self, edn: &'a EdnItem<S>) -> Option<Box<dyn Render<TuiOut> + 'a>> {
|
||||
(|$self:ident:$State:ty|{ $($pat:pat => $expr:expr),* $(,)? }) => {
|
||||
impl<'a, E: Output> EdnProvide<'a, Box<dyn Render<E> + 'a>> for $State {
|
||||
fn get <S: AsRef<str>> (&'a $self, edn: &'a EdnItem<S>) -> Option<Box<dyn Render<E> + 'a>> {
|
||||
Some(match edn.to_ref() {
|
||||
$(EdnItem::Sym($pat) => $expr),*,
|
||||
_ => return None
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
($Output:ty: |$self:ident:$State:ty|{ $($pat:pat => $expr:expr),* $(,)? }) => {
|
||||
impl<'a> EdnProvide<'a, Box<dyn Render<$Output> + 'a>> for $State {
|
||||
fn get <S: AsRef<str>> (&'a $self, edn: &'a EdnItem<S>) -> Option<Box<dyn Render<$Output> + 'a>> {
|
||||
Some(match edn.to_ref() {
|
||||
$(EdnItem::Sym($pat) => $expr),*,
|
||||
_ => return None
|
||||
|
|
@ -15,21 +46,23 @@ use EdnItem::*;
|
|||
}
|
||||
}
|
||||
/// Renders from EDN source and context.
|
||||
#[derive(Default)]
|
||||
pub enum EdnView<'a, E: Output, T: EdnViewData<'a, E> + std::fmt::Debug> {
|
||||
#[default]
|
||||
Inert,
|
||||
_Unused(PhantomData<&'a E>),
|
||||
#[derive(Default)] pub enum EdnView<'a, E: Output, T: EdnViewData<'a, E> + std::fmt::Debug> {
|
||||
#[default] Inert,
|
||||
Ok(T, EdnItem<&'a str>),
|
||||
//render: Box<dyn Fn(&'a T)->Box<dyn Render<E> + Send + Sync + 'a> + Send + Sync + 'a>
|
||||
Err(String)
|
||||
Err(String),
|
||||
_Unused(PhantomData<&'a E>),
|
||||
}
|
||||
impl<'a, E: Output, T: EdnViewData<'a, E> + std::fmt::Debug> std::fmt::Debug for EdnView<'a, E, T> {
|
||||
fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
match self {
|
||||
Self::Inert | Self::_Unused(_) => write!(f, "EdnView::Inert"),
|
||||
Self::Ok(state, view) => write!(f, "EdnView::Ok(state={state:?} view={view:?}"),
|
||||
Self::Err(error) => write!(f, "EdnView::Err({error})"),
|
||||
Self::Inert | Self::_Unused(_) =>
|
||||
write!(f, "EdnView::Inert"),
|
||||
Self::Ok(state, view) =>
|
||||
write!(f, "EdnView::Ok(state={state:?} view={view:?}"),
|
||||
Self::Err(error) =>
|
||||
write!(f, "EdnView::Err({error})"),
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,42 +66,35 @@ pub type Perhaps<T> = Result<Option<T>, Box<dyn Error>>;
|
|||
#[cfg(test)] #[test] fn test_layout () -> Usually<()> {
|
||||
use ::tek_tui::{*, tek_output::*};
|
||||
let area: [u16;4] = [10, 10, 20, 20];
|
||||
|
||||
let unit = ();
|
||||
|
||||
assert_eq!(Content::<TuiOut>::layout(&unit, area), [20, 20, 0, 0]);
|
||||
|
||||
assert_eq!(Content::<TuiOut>::layout(&Fill::<()>::x(unit), area), [10, 20, 20, 0]);
|
||||
assert_eq!(Render::<TuiOut>::layout(&Fill::<()>::x(unit), area), [10, 20, 20, 0]);
|
||||
|
||||
assert_eq!(Fill::<()>::y(unit).layout(area), [20, 10, 0, 20]);
|
||||
assert_eq!(Fill::<()>::xy(unit).layout(area), area);
|
||||
|
||||
assert_eq!(Fixed::<TuiOut, u16>::x(4, unit).layout(area), [18, 20, 4, 0]);
|
||||
assert_eq!(Fixed::<TuiOut, u16>::y(4, unit).layout(area), [20, 18, 0, 4]);
|
||||
assert_eq!(Fixed::<TuiOut, u16>::xy(4, 4, unit).layout(area), [18, 18, 4, 4]);
|
||||
|
||||
let four = ||Fixed::<TuiOut, _>::xy(4, 4, unit);
|
||||
|
||||
assert_eq!(Align::nw(four()).layout(area), [10, 10, 4, 4]);
|
||||
assert_eq!(Align::n(four()).layout(area), [18, 10, 4, 4]);
|
||||
assert_eq!(Align::ne(four()).layout(area), [26, 10, 4, 4]);
|
||||
assert_eq!(Align::e(four()).layout(area), [26, 18, 4, 4]);
|
||||
assert_eq!(Align::se(four()).layout(area), [26, 26, 4, 4]);
|
||||
assert_eq!(Align::s(four()).layout(area), [18, 26, 4, 4]);
|
||||
assert_eq!(Align::sw(four()).layout(area), [10, 26, 4, 4]);
|
||||
assert_eq!(Align::w(four()).layout(area), [10, 18, 4, 4]);
|
||||
|
||||
let two_by_four = ||Fixed::<TuiOut, _>::xy(4, 2, unit);
|
||||
|
||||
assert_eq!(Align::nw(two_by_four()).layout(area), [10, 10, 4, 2]);
|
||||
assert_eq!(Align::n(two_by_four()).layout(area), [18, 10, 4, 2]);
|
||||
assert_eq!(Align::ne(two_by_four()).layout(area), [26, 10, 4, 2]);
|
||||
assert_eq!(Align::e(two_by_four()).layout(area), [26, 19, 4, 2]);
|
||||
assert_eq!(Align::se(two_by_four()).layout(area), [26, 28, 4, 2]);
|
||||
assert_eq!(Align::s(two_by_four()).layout(area), [18, 28, 4, 2]);
|
||||
assert_eq!(Align::sw(two_by_four()).layout(area), [10, 28, 4, 2]);
|
||||
assert_eq!(Align::w(two_by_four()).layout(area), [10, 19, 4, 2]);
|
||||
|
||||
fn test (area: [u16;4], item: &impl Content<TuiOut>, expected: [u16;4]) {
|
||||
assert_eq!(Content::layout(item, area), expected);
|
||||
assert_eq!(Render::layout(item, area), expected);
|
||||
};
|
||||
test(area, &(), [20, 20, 0, 0]);
|
||||
test(area, &Fill::xy(()), area);
|
||||
test(area, &Fill::x(()), [10, 20, 20, 0]);
|
||||
test(area, &Fill::y(()), [20, 10, 0, 20]);
|
||||
test(area, &Fixed::x(4, unit), [18, 20, 4, 0]);
|
||||
test(area, &Fixed::y(4, unit), [20, 18, 0, 4]);
|
||||
test(area, &Fixed::xy(4, 4, unit), [18, 18, 4, 4]);
|
||||
let four = ||Fixed::<TuiOut, _, _>::xy(4, 4, unit);
|
||||
test(area, &Align::nw(four()), [10, 10, 4, 4]);
|
||||
test(area, &Align::n(four()), [18, 10, 4, 4]);
|
||||
test(area, &Align::ne(four()), [26, 10, 4, 4]);
|
||||
test(area, &Align::e(four()), [26, 18, 4, 4]);
|
||||
test(area, &Align::se(four()), [26, 26, 4, 4]);
|
||||
test(area, &Align::s(four()), [18, 26, 4, 4]);
|
||||
test(area, &Align::sw(four()), [10, 26, 4, 4]);
|
||||
test(area, &Align::w(four()), [10, 18, 4, 4]);
|
||||
let two_by_four = ||Fixed::<TuiOut, _, _>::xy(4, 2, unit);
|
||||
test(area, &Align::nw(two_by_four()), [10, 10, 4, 2]);
|
||||
test(area, &Align::n(two_by_four()), [18, 10, 4, 2]);
|
||||
test(area, &Align::ne(two_by_four()), [26, 10, 4, 2]);
|
||||
test(area, &Align::e(two_by_four()), [26, 19, 4, 2]);
|
||||
test(area, &Align::se(two_by_four()), [26, 28, 4, 2]);
|
||||
test(area, &Align::s(two_by_four()), [18, 28, 4, 2]);
|
||||
test(area, &Align::sw(two_by_four()), [10, 28, 4, 2]);
|
||||
test(area, &Align::w(two_by_four()), [10, 19, 4, 2]);
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue