wip: edn minefield

This commit is contained in:
🪞👃🪞 2025-01-04 12:23:33 +01:00
parent 98d2107e4e
commit 6f51872856
7 changed files with 150 additions and 210 deletions

View file

@ -1,150 +1,68 @@
use crate::*;
use std::marker::PhantomData;
use ::tek_layout::{*, tek_engine::{Content, Render, Engine, Thunk}};
use ::tek_layout::{*, tek_engine::{Usually, Content, Render, Engine, Thunk}};
use Item::*;
pub struct EdnContent<'a, E, T: AsRef<str>>(PhantomData<E>, &'a [Item<T>]);
//pub struct EdnContent<'a, E, T: AsRef<str>>(PhantomData<E>, &'a [Item<T>]);
impl<'a, E, T: AsRef<str>> From<&'a [Item<T>]> for EdnContent<'a, E, T> {
fn from (items: &'a [Item<T>]) -> Self {
Self(Default::default(), items)
//impl<'a, E, T: AsRef<str>> From<&'a [Item<T>]> for EdnContent<'a, E, T> {
//fn from (items: &'a [Item<T>]) -> Self {
//Self(Default::default(), items)
//}
//}
pub struct EdnView<'a, E: Engine + 'a, T: EdnLayout<'a, E> + 'a>(
PhantomData<&'a ()>,
Box<dyn Fn(T)->Box<dyn Render<E> + Send + Sync> + Send + Sync>
);
impl<'a, E: Engine + 'a, T: EdnLayout<'a, E> + 'a> EdnView<'a, E, T> {
fn from (source: &'a str) -> Usually<Self> {
let items: Vec<Item<&'a str>> = Item::read_all(source)?;
let layout = T::parse(items.iter().map(|x|x.to_str()).collect::<Vec<_>>().as_slice());
Ok(Self(Default::default(), Box::new(move|_|{
let _ = layout;
Box::new(())
})))
}
}
//impl<'a, E: Engine> Content<E> for EdnContent<'a, E> {
/*todo*/
//}
//pub struct EdnContent<'a, T>(T, &'a [Item]);
pub trait EdnLayout<E: Engine + 'static> {
fn get_bool (&self, item: &Item<&str>) -> bool { false }
fn get_unit (&self, item: &Item<&str>) -> E::Unit { 0.into() }
fn get_usize (&self, key: &str) -> usize { 0 }
fn get_content (&self, item: &Item<&str>) -> Box<dyn Render<E> + '_> { Box::new(()) }
fn parse <'a: 'static> (&'a self, items: &[Item<&str>]) -> Box<dyn Render<E> + 'a> {
match items {
[Key("when"), c, a, ..] =>
Box::new(When(self.get_bool(c), self.get_content(a))),
[Key("either"), c, a, b, ..] =>
Box::new(Either(self.get_bool(c), self.get_content(a), self.get_content(b))),
[Key("fill"), a, ..] =>
Box::new(Fill::xy(self.get_content(a))),
[Key("fill/x"), a, ..] => Box::new(Fill::x(self.get_content(a))),
[Key("fill/y"), a, ..] => Box::new(Fill::y(self.get_content(a))),
[Key("fixed"), x, y, a, ..] =>
Box::new(Fixed::xy(self.get_unit(x), self.get_unit(y), self.get_content(a))),
[Key("fixed/x"), x, a, ..] => Box::new(Fixed::x(self.get_unit(x), self.get_content(a))),
[Key("fixed/y"), y, a, ..] => Box::new(Fixed::y(self.get_unit(y), self.get_content(a))),
[Key("shrink"), x, y, a, ..] =>
Box::new(Shrink::xy(self.get_unit(x), self.get_unit(y), self.get_content(a))),
[Key("shrink/x"), x, a, ..] => Box::new(Shrink::x(self.get_unit(x), self.get_content(a))),
[Key("shrink/y"), y, a, ..] => Box::new(Shrink::y(self.get_unit(y), self.get_content(a))),
[Key("expand"), x, y, a, ..] =>
Box::new(Expand::xy(self.get_unit(x), self.get_unit(y), self.get_content(a))),
[Key("expand/x"), x, a, ..] => Box::new(Expand::x(self.get_unit(x), self.get_content(a))),
[Key("expand/y"), y, a, ..] => Box::new(Expand::y(self.get_unit(y), self.get_content(a))),
[Key("push"), x, y, a, ..] =>
Box::new(Push::xy(self.get_unit(x), self.get_unit(y), self.get_content(a))),
[Key("push/x"), x, a, ..] => Box::new(Push::x(self.get_unit(x), self.get_content(a))),
[Key("push/y"), y, a, ..] => Box::new(Push::y(self.get_unit(y), self.get_content(a))),
[Key("pull"), x, y, a, ..] =>
Box::new(Pull::xy(self.get_unit(x), self.get_unit(y), self.get_content(a))),
[Key("pull/x"), x, a, ..] => Box::new(Pull::x(self.get_unit(x), self.get_content(a))),
[Key("pull/y"), y, a, ..] => Box::new(Pull::y(self.get_unit(y), self.get_content(a))),
_ => Box::new(())
//[Key("when"), Sym(condition), Sym(template)] => When(
//self.get_bool(condition),
//self.get_content(template)),
//[Key("when"), Sym(condition), Exp(template)] => When(
//self.get_bool(condition),
//Thunk::new(||EdnLayout::parse(template))),
macro_rules! edn_ns {
(|$state:ident, $items:ident| { $($match:pat => $handle:expr),* $(,)? }) => {
match $items {
$($match => |$state|Box::new($handle),)*
_ => |$state|Box::new(())
}
}
}
//edn_ns! { EdnLayout |context, item| {
//[Key("when"), Sym(condition), Sym(template)] => When(
//context.get_bool(condition),
//context.get_template(template)),
//[Key("when"), Sym(condition), Exp(template)] => When(
//context.get_bool(condition),
//Thunk::new(||EdnLayout::parse(template))),
//"when" => When(item.0[1].into(), item.0[2].into())
////"either" = Either<A, B>(args[0].into(), args[1].into(), args[2].into()),
////"map" = Map<A, B, I, F, G>(args[0].into(), args[1].into()),
////"fill" = edn_ns! {
////"x" = Fixed<T>::X(args[0].into(), args[1].into()),
////"y" = Fixed<T>::Y(args[0].into(), args[1].into()),
////"xy" = Fixed<T>::XY(args[0].into(), args[1].into(), args[2].into()),
////},
////"fixed" = edn_ns! {
////"x" = Fixed<T>::X(args[0].into(), args[1].into()),
////"y" = Fixed<T>::Y(args[0].into(), args[1].into()),
////"xy" = Fixed<T>::XY(args[0].into(), args[1].into(), args[2].into()),
////},
////"shrink" = edn_ns! {
////"x" = Shrink<T>::X(args[0].into(), args[1].into()),
////"y" = Shrink<T>::Y(args[0].into(), args[1].into()),
////"xy" = Shrink<T>::XY(args[0].into(), args[1].into(), args[2].into()),
////},
////"expand" = edn_ns! {
////"x" = Expand<T>::X(args[0].into(), args[1].into()),
////"y" = Expand<T>::Y(args[0].into(), args[1].into()),
////"xy" = Expand<T>::XY(args[0].into(), args[1].into(), args[2].into()),
////},
////"min" = edn_ns! {
////"x" = Min<T>::X(args[0].into(), args[1].into()),
////"y" = Min<T>::Y(args[0].into(), args[1].into()),
////"xy" = Min<T>::XY(args[0].into(), args[1].into(), args[2].into()),
////},
////"max" = edn_ns! {
////"x" = Max<T>::X(args[0].into(), args[1].into()),
////"y" = Max<T>::Y(args[0].into(), args[1].into()),
////"xy" = Max<T>::XY(args[0].into(), args[1].into(), args[2].into()),
////},
////"push" = edn_ns! {
////"x" = Push<T>::X(args[0].into(), args[1].into()),
////"y" = Push<T>::Y(args[0].into(), args[1].into()),
////"xy" = Push<T>::XY(args[0].into(), args[1].into(), args[2].into()),
////},
////"pull" = edn_ns! {
////"x" = Pull<T>::X(args[0].into(), args[1].into()),
////"y" = Pull<T>::Y(args[0].into(), args[1].into()),
////"xy" = Pull<T>::XY(args[0].into(), args[1].into(), args[2].into()),
////},
////"margin" = edn_ns! {
////"x" = Margin<T>::X(args[0].into(), args[1].into()),
////"y" = Margin<T>::Y(args[0].into(), args[1].into()),
////"xy" = Margin<T>::XY(args[0].into(), args[1].into(), args[2].into()),
////},
////"padding" = edn_ns! {
////"x" = Padding<T>::X(args[0].into(), args[1].into()),
////"y" = Padding<T>::Y(args[0].into(), args[1].into()),
////"xy" = Padding<T>::XY(args[0].into(), args[1].into(), args[2].into()),
////},
//} }
pub trait EdnLayout<'a, E: Engine> where Self: 'a {
fn get_bool (&self, _: &Item<&str>) -> bool { false }
fn get_unit (&self, _: &Item<&str>) -> E::Unit { 0.into() }
fn get_usize (&self, _: &Item<&str>) -> usize { 0 }
fn get_content (&self, _: &Item<&str>) -> Box<dyn Render<E>> { Box::new(()) }
fn parse (items: &'a [Item<&'a str>]) -> impl Fn(&'a Self)->Box<dyn Render<E> + 'a> + 'a {
edn_ns!(|state, items|{
[Key("when"), c, a, ..] => When(state.get_bool(c), state.get_content(a)),
[Key("either"), c, a, b, ..] => Either(state.get_bool(c), state.get_content(a), state.get_content(b)),
[Key("fill"), a, ..] => Fill::xy(state.get_content(a)),
[Key("fill/x"), a, ..] => Fill::x(state.get_content(a)),
[Key("fill/y"), a, ..] => Fill::y(state.get_content(a)),
[Key("fixed"), x, y, a, ..] => Fixed::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
[Key("fixed/x"), x, a, ..] => Fixed::x(state.get_unit(x), state.get_content(a)),
[Key("fixed/y"), y, a, ..] => Fixed::y(state.get_unit(y), state.get_content(a)),
[Key("shrink"), x, y, a, ..] => Shrink::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
[Key("shrink/x"), x, a, ..] => Shrink::x(state.get_unit(x), state.get_content(a)),
[Key("shrink/y"), y, a, ..] => Shrink::y(state.get_unit(y), state.get_content(a)),
[Key("expand"), x, y, a, ..] => Expand::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
[Key("expand/x"), x, a, ..] => Expand::x(state.get_unit(x), state.get_content(a)),
[Key("expand/y"), y, a, ..] => Expand::y(state.get_unit(y), state.get_content(a)),
[Key("push"), x, y, a, ..] => Push::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
[Key("push/x"), x, a, ..] => Push::x(state.get_unit(x), state.get_content(a)),
[Key("push/y"), y, a, ..] => Push::y(state.get_unit(y), state.get_content(a)),
[Key("pull"), x, y, a, ..] => Pull::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
[Key("pull/x"), x, a, ..] => Pull::x(state.get_unit(x), state.get_content(a)),
[Key("pull/y"), y, a, ..] => Pull::y(state.get_unit(y), state.get_content(a)),
})
}
}