mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
separate Input and Output impls
This commit is contained in:
parent
a6efde40f8
commit
0e821e098f
77 changed files with 465 additions and 454 deletions
|
|
@ -17,23 +17,27 @@ fn main () -> Usually<()> {
|
|||
pub struct Example(usize);
|
||||
|
||||
impl EdnViewData<Tui> for &Example {
|
||||
fn get_content <'a> (&'a self, sym: &'a str) -> RenderBox<'a, Tui> {
|
||||
fn get_content <'a> (&'a self, sym: EdnItem<&'a str>) -> RenderBox<'a, Tui> {
|
||||
Box::new(Thunk::new(move||match sym {
|
||||
":hello-world" => "Hello world!",
|
||||
":hello" => "Hello",
|
||||
":world" => "world",
|
||||
EdnItem::Sym(":hello-world") => "Hello world!",
|
||||
EdnItem::Sym(":hello") => "Hello",
|
||||
EdnItem::Sym(":world") => "world",
|
||||
_ => ""
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl Content<Tui> for Example {
|
||||
fn content (&self) -> impl Render<Tui> {
|
||||
EdnView::new(self, EDN[self.0]).unwrap()
|
||||
impl Content<TuiOut> for Example {
|
||||
fn content (&self) -> impl Render<TuiOut> {
|
||||
Bsp::a(
|
||||
&format!("{}", self.0),
|
||||
EdnView::new(self, EDN[self.0])
|
||||
.unwrap_or_else(|e|format!("Failed to render {}: {e}", self.0))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Handle<Tui> for Example {
|
||||
impl Handle<TuiIn> for Example {
|
||||
fn handle (&mut self, input: &TuiIn) -> Perhaps<bool> {
|
||||
match input.event() {
|
||||
kpat!(Right) => self.0 = (self.0 + 1) % EDN.len(),
|
||||
|
|
@ -22,10 +22,10 @@ impl EdnViewData<Tui> for &Example {
|
|||
}
|
||||
}
|
||||
|
||||
impl Content<Tui> for Example {
|
||||
fn content (&self) -> impl Render<Tui> {
|
||||
impl Content<TuiOut> for Example {
|
||||
fn content (&self) -> impl Render<TuiOut> {
|
||||
EdnView::new(self, EDN).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Handle<Tui> for Example {}
|
||||
impl Handle<TuiIn> for Example {}
|
||||
|
|
|
|||
|
|
@ -1,56 +1,62 @@
|
|||
use crate::*;
|
||||
use std::marker::PhantomData;
|
||||
use ::tek_layout::{*, tek_engine::{Usually, Content, Render, RenderBox, Engine, Thunk}};
|
||||
use ::tek_layout::{*, tek_engine::{Usually, Content, Render, RenderBox, Output, Thunk}};
|
||||
use EdnItem::*;
|
||||
|
||||
pub type EdnCallback<'a, Engine, State> =
|
||||
dyn Fn(&'a State)-> RenderBox<'a, Engine> + Send + Sync + 'a;
|
||||
pub type EdnCallback<'a, Output, State> =
|
||||
dyn Fn(&'a State)-> RenderBox<'a, Output> + Send + Sync + 'a;
|
||||
|
||||
pub type EdnRenderCallback<'a, Engine, State> =
|
||||
Box<EdnCallback<'a, Engine, State>>;
|
||||
pub type EdnRenderCallback<'a, Output, State> =
|
||||
Box<EdnCallback<'a, Output, State>>;
|
||||
|
||||
pub trait EdnViewData<E: Engine> {
|
||||
pub trait EdnViewData<E: Output> {
|
||||
fn get_bool (&self, _sym: EdnItem<&str>) -> bool { false }
|
||||
fn get_unit (&self, _sym: EdnItem<&str>) -> E::Unit { 0.into() }
|
||||
fn get_usize (&self, _sym: EdnItem<&str>) -> usize { 0 }
|
||||
fn get_content <'a> (&'a self, _sym: EdnItem<&str>) -> RenderBox<'a, E> { Box::new(()) }
|
||||
fn get_content <'a> (&'a self, _sym: EdnItem<&'a str>) -> RenderBox<'a, E> { Box::new(()) }
|
||||
}
|
||||
|
||||
/// Renders from EDN source and context.
|
||||
pub struct EdnView<E: Engine, T: EdnViewData<E>> {
|
||||
_engine: PhantomData<E>,
|
||||
context: T,
|
||||
layout: EdnItem<String>
|
||||
pub enum EdnView<E: Output, T: EdnViewData<E>> {
|
||||
_Unused(PhantomData<E>),
|
||||
Ok(T, EdnItem<String>),
|
||||
//render: Box<dyn Fn(&'a T)->Box<dyn Render<E> + Send + Sync + 'a> + Send + Sync + 'a>
|
||||
Err(String)
|
||||
}
|
||||
|
||||
impl<E: Engine, T: EdnViewData<E>> EdnView<E, T> {
|
||||
impl<E: Output, T: EdnViewData<E>> EdnView<E, T> {
|
||||
pub fn new (context: T, source: &str) -> Usually<Self> {
|
||||
let layout = EdnItem::read_one(&source)?.0;
|
||||
Ok(Self { _engine: Default::default(), context, layout, })
|
||||
Ok(Self::Ok(context, layout))
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Engine, T: EdnViewData<E> + Send + Sync> Content<E> for EdnView<E, T> {
|
||||
impl<E: Output, T: EdnViewData<E> + Send + Sync> Content<E> for EdnView<E, T> {
|
||||
fn content (&self) -> impl Render<E> {
|
||||
use EdnItem::*;
|
||||
match &self.layout {
|
||||
Nil => ().boxed(),
|
||||
Sym(t) => self.context.get_content(Sym(t.as_str())).boxed(),
|
||||
Key(t) => panic!("todo: add error handling to content() chain. unexpected key {t}"),
|
||||
Num(n) => panic!("todo: add error handling to content() chain. unexpected num {n}"),
|
||||
Exp(e) => if let [head, tail @ ..] = e.as_slice() {
|
||||
let head = &head.to_ref();
|
||||
let state = &self.context;
|
||||
match (head, tail) {
|
||||
(Key("when"), [c, a]) => When(state.get_bool(c.to_ref()), state.get_content(a.to_ref())).boxed(),
|
||||
(Key("bsp/s"), [a, b]) => Bsp::s(state.get_content(a.to_ref()), state.get_content(b.to_ref()),).boxed(),
|
||||
_ => todo!("{:?} {:?}", &head, &tail)
|
||||
}
|
||||
} else {
|
||||
panic!("todo: add error handling to content() chain. invalid expression {e:?}")
|
||||
match self {
|
||||
Self::Ok(state, layout) => match layout {
|
||||
Nil => ().boxed(),
|
||||
Sym(t) => state.get_content(Sym(t.as_str())).boxed(),
|
||||
Key(t) => panic!("todo: add error handling to content() chain. unexpected key {t}"),
|
||||
Num(n) => panic!("todo: add error handling to content() chain. unexpected num {n}"),
|
||||
Exp(e) => if let [head, tail @ ..] = e.as_slice() {
|
||||
let head = &head.to_ref();
|
||||
match (head, tail) {
|
||||
(Key("when"), [c, a]) => When(state.get_bool(c.to_ref()), state.get_content(a.to_ref())).boxed(),
|
||||
(Key("bsp/s"), [a, b]) => Bsp::s(state.get_content(a.to_ref()), state.get_content(b.to_ref()),).boxed(),
|
||||
_ => todo!("{:?} {:?}", &head, &tail)
|
||||
}
|
||||
} else {
|
||||
panic!("todo: add error handling to content() chain. invalid expression {e:?}")
|
||||
},
|
||||
},
|
||||
Self::Err(error) => {
|
||||
Box::new(())//&format!("EdnView error: {error:?}"))
|
||||
},
|
||||
_ => todo!()
|
||||
}
|
||||
|
||||
//let items = &self.layout;
|
||||
//if let (Some(first), rest) = (items.get(0).map(EdnItem::to_str), &items[1..]) {
|
||||
//match (first, rest) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue