mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-08 04:36:45 +01:00
wip: reenable dynamic dispatch
This commit is contained in:
parent
600d0b3aca
commit
ac3827b8f3
11 changed files with 997 additions and 194 deletions
|
|
@ -1,118 +1,194 @@
|
|||
use crate::*;
|
||||
use std::marker::PhantomData;
|
||||
use ::tek_layout::{*, tek_engine::{Content, Render, Engine, Thunk}};
|
||||
use Item::*;
|
||||
|
||||
#[cfg(test)] #[test] fn test_edn_layout () -> Result<(), ParseError> {
|
||||
let source = include_str!("example.edn");
|
||||
let layout = Item::read_all(source)?;
|
||||
panic!("{layout:?}");
|
||||
let content = EdnLayout::from(&layout);
|
||||
Ok(())
|
||||
}
|
||||
pub struct EdnContent<'a, E, T: AsRef<str>>(PhantomData<E>, &'a [Item<T>]);
|
||||
|
||||
impl<'a> From<&'a [Item]> for EdnLayout<'a> {
|
||||
fn from (items: &'a [Item]) -> Self {
|
||||
Self(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 EdnLayout<'a, E>(&'a [Item]);
|
||||
impl<'a, E> EdnLayout<'a, E> {
|
||||
fn get_content (&self) -> impl Content<E> {
|
||||
}
|
||||
}
|
||||
//impl<'a, E: Engine> Content<E> for EdnContent<'a, E> {
|
||||
/*todo*/
|
||||
//}
|
||||
|
||||
//pub struct EdnContent<'a, T>(T, &'a [Item]);
|
||||
|
||||
#[macro_export] macro_rules! edn_ns {
|
||||
($name:literal = $Host:ident<$E:ident: $Engine:path> |$args:ident| { $(
|
||||
($fn:literal
|
||||
$Struct:ident
|
||||
$(<$($G:ident$(: $Generic:ty)?),+>)?
|
||||
$(::$Variant:ident)?
|
||||
($($arg:expr),*))
|
||||
)* }) => {
|
||||
//pub trait $Host<$E: Engine> {
|
||||
//fn read_one <'e> (edn: &[Edn<'e>]) -> impl Content<$E> {
|
||||
//if let Some(Edn::Symbol(name)) = edn.get(0) {
|
||||
//match *name {
|
||||
//$(
|
||||
//$fn => $Struct$(::$Variant)?($($arg),+),
|
||||
//)*
|
||||
//_ => {}
|
||||
//}
|
||||
//} else {
|
||||
//panic!("invalid edn")
|
||||
//}
|
||||
//}
|
||||
//}
|
||||
};
|
||||
pub trait EdnLayout<E: Engine + 'static> {
|
||||
fn get_bool (&self, item: &Item<&str>) -> bool { todo!() }
|
||||
fn get_unit (&self, item: &Item<&str>) -> E::Unit { todo!() }
|
||||
fn get_usize (&self, key: &str) -> usize { todo!() }
|
||||
fn get_content (&self, item: &Item<&str>) -> &dyn Render<E> { todo!() }
|
||||
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))),
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
edn_ns! {
|
||||
macro_rules! edn_context {
|
||||
($Struct:ident |$l:lifetime, $state:ident| {
|
||||
$($key:literal = $field:ident: $Type:ty => $expr:expr,)*
|
||||
}) => {
|
||||
|
||||
"when" = When<A>(args[0].into(), args[1].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()),
|
||||
},
|
||||
#[derive(Default)]
|
||||
pub struct EdnView<$l> { $($field: Option<$Type>),* }
|
||||
|
||||
impl<$l> EdnView<$l> {
|
||||
pub fn parse <'e> (edn: &[Edn<'e>]) -> impl Fn(&$Struct) + use<'e> {
|
||||
let imports = Self::imports_all(edn);
|
||||
move |state| {
|
||||
let mut context = EdnView::default();
|
||||
for import in imports.iter() {
|
||||
context.import(state, import)
|
||||
}
|
||||
}
|
||||
}
|
||||
fn imports_all <'e> (edn: &[Edn<'e>]) -> Vec<&'e str> {
|
||||
let mut imports = vec![];
|
||||
for edn in edn.iter() {
|
||||
for import in Self::imports_one(edn) {
|
||||
imports.push(import);
|
||||
}
|
||||
}
|
||||
imports
|
||||
}
|
||||
fn imports_one <'e> (edn: &Edn<'e>) -> Vec<&'e str> {
|
||||
match edn {
|
||||
Edn::Symbol(import) => vec![import],
|
||||
Edn::List(edn) => Self::imports_all(edn.as_slice()),
|
||||
_ => vec![],
|
||||
}
|
||||
}
|
||||
pub fn import (&mut self, $state: &$l$Struct, key: &str) {
|
||||
match key {
|
||||
$($key => self.$field = Some($expr),)*
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//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()),
|
||||
////},
|
||||
|
||||
//} }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue