wip: still trying to write the iterator

This commit is contained in:
🪞👃🪞 2025-01-05 04:07:27 +01:00
parent 140fd22223
commit 433e4df0f2
7 changed files with 114 additions and 66 deletions

14
Cargo.lock generated
View file

@ -524,6 +524,15 @@ dependencies = [
"either",
]
[[package]]
name = "itertools"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.14"
@ -982,7 +991,7 @@ dependencies = [
"crossterm",
"indoc",
"instability",
"itertools",
"itertools 0.13.0",
"lru",
"paste",
"strum",
@ -1422,6 +1431,7 @@ name = "tek_edn"
version = "0.1.0"
dependencies = [
"clojure-reader",
"itertools 0.14.0",
"konst",
"tek_layout",
]
@ -1529,7 +1539,7 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf"
dependencies = [
"itertools",
"itertools 0.13.0",
"unicode-segmentation",
"unicode-width 0.1.14",
]

14
edn/Cargo.lock generated
View file

@ -279,6 +279,15 @@ dependencies = [
"either",
]
[[package]]
name = "itertools"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.14"
@ -468,7 +477,7 @@ dependencies = [
"crossterm",
"indoc",
"instability",
"itertools",
"itertools 0.13.0",
"lru",
"paste",
"strum",
@ -609,6 +618,7 @@ name = "tek_edn"
version = "0.1.0"
dependencies = [
"clojure-reader",
"itertools 0.14.0",
"konst",
"tek_layout",
]
@ -662,7 +672,7 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf"
dependencies = [
"itertools",
"itertools 0.13.0",
"unicode-segmentation",
"unicode-width 0.1.14",
]

View file

@ -6,6 +6,7 @@ version = "0.1.0"
[dependencies]
clojure-reader = "0.3.0"
konst = "0.3.16"
itertools = "0.14.0"
tek_layout = { optional = true, path = "../layout" }
[features]

View file

@ -12,6 +12,19 @@ impl<T> Default for EdnItem<T> {
Self::Nil
}
}
impl<T: Debug> Debug for EdnItem<T> {
fn fmt (&self, f: &mut Formatter<'_>) -> Result<(), FormatError> {
match self {
Self::Nil => write!(f, "Nil"),
Self::Num(u) => write!(f, "Num({u})"),
Self::Sym(u) => write!(f, "Sym({u:?})"),
Self::Key(u) => write!(f, "Key({u:?})"),
Self::Exp(e) => write!(f, "Exp({})", itertools::join(
e.iter().map(|i|format!("{:?}", i)), ","
))
}
}
}
impl<T: AsRef<str> + PartialEq + Default + Clone + std::fmt::Debug> EdnItem<T> {
pub fn to_ref (&self) -> EdnItem<&str> {
match self {
@ -25,40 +38,42 @@ impl<T: AsRef<str> + PartialEq + Default + Clone + std::fmt::Debug> EdnItem<T> {
_ => todo!()
}
}
pub fn symbols <'a> (&'a self) -> SymIterator<'a, T> {
SymIterator::new(&self)
pub fn symbols <'a> (&'a self) -> EdnIterator<'a, T> {
EdnIterator::new(&self)
}
}
enum SymIterator<'a, T> {
enum EdnIterator<'a, T>{
Nil,
Sym(&'a T),
Exp(&'a [EdnItem<T>])
Exp(Vec<EdnIterator<'a, T>>)
}
impl<'a, T: AsRef<str>> SymIterator<'a, T> {
impl<'a, T: AsRef<str>> EdnIterator<'a, T> {
fn new (item: &'a EdnItem<T>) -> Self {
use EdnItem::*;
match item {
Sym(t) => Self::Sym(t),
Exp(i) => Self::Exp(i.as_slice()),
Exp(i) => Self::Exp(i.iter().map(EdnIterator::new).collect()),
_ => Self::Nil,
}
}
}
impl<'a, T: AsRef<str>> Iterator for SymIterator<'a, T> {
type Item = &'a str;
impl<'a, T: AsRef<str>> Iterator for EdnIterator<'a, T> {
type Item = &'a T;
fn next (&mut self) -> Option<Self::Item> {
use SymIterator::*;
use EdnIterator::*;
match self {
Sym(t) => {
let t = *t;
*self = Nil;
Some(t.as_ref())
Some(t)
},
Exp([a, b @ ..]) => match a {
EdnItem::Sym(t) => {
*self = Exp(b);
Some(t.as_ref())
}
EdnItem::Exp(_) => todo!(),
Exp(v) => match v.as_mut_slice() {
[a] => if let Some(next) = a.next() {
Some(next)
} else {
*self = Exp(v.split_off(1));
self.next()
},
_ => {
*self = Nil;
None

View file

@ -13,43 +13,8 @@ pub type EdnRenderCallback<'a, Engine, State> =
Box<EdnCallback<'a, Engine, State>>;
pub trait EdnLayout<'a, E: Engine + 'a> where Self: 'a {
fn get_bool (&self, _: &EdnItem<&str>) -> bool { false }
fn get_unit (&self, _: &EdnItem<&str>) -> E::Unit { 0.into() }
fn get_usize (&self, _: &EdnItem<&str>) -> usize { 0 }
fn get_content (&'a self, _: &EdnItem<&str>) -> Box<EdnRender<'a, E>> { Box::new(()) }
fn parse (items: &'a [EdnItem<String>]) -> EdnRenderCallback<'a, E, Self> {
if let (Some(first), rest) = (items.get(0).map(EdnItem::to_str), &items[1..]) {
match (first, rest) {
("when", [c, a, ..]) => Box::new(move|state|Box::new(
When(state.get_bool(&c.to_ref()), state.get_content(&a.to_ref())))),
_ => Box::new(|_|Box::new(()))
}
} else {
Box::new(|_|Box::new(()))
}
}
//Box::new(match [items.get(0).map(|x|x.to_str()), items[1..]] {
//["when", [c, a, ..]] => When(state.get_bool(c), state.get_content(a)),
//["either", [c, a, b, ..]] => Either(state.get_bool(c), state.get_content(a), state.get_content(b)),
//["fill", [a, ..]] => Fill::xy(state.get_content(a)),
//["fill/x", [a, ..]] => Fill::x(state.get_content(a)),
//["fill/y", [a, ..]] => Fill::y(state.get_content(a)),
//["fixed", [x, y, a, ..]] => Fixed::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
//["fixed/x", [x, a, ..]] => Fixed::x(state.get_unit(x), state.get_content(a)),
//["fixed/y", [y, a, ..]] => Fixed::y(state.get_unit(y), state.get_content(a)),
//["shrink", [x, y, a, ..]] => Shrink::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
//["shrink/x", [x, a, ..]] => Shrink::x(state.get_unit(x), state.get_content(a)),
//["shrink/y", [y, a, ..]] => Shrink::y(state.get_unit(y), state.get_content(a)),
//["expand", [x, y, a, ..]] => Expand::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
//["expand/x", [x, a, ..]] => Expand::x(state.get_unit(x), state.get_content(a)),
//["expand/y", [y, a, ..]] => Expand::y(state.get_unit(y), state.get_content(a)),
//["push", [x, y, a, ..]] => Push::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
//["push/x", [x, a, ..]] => Push::x(state.get_unit(x), state.get_content(a)),
//["push/y", [y, a, ..]] => Push::y(state.get_unit(y), state.get_content(a)),
//["pull", [x, y, a, ..]] => Pull::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
//["pull/x", [x, a, ..]] => Pull::x(state.get_unit(x), state.get_content(a)),
//["pull/y", [y, a, ..]] => Pull::y(state.get_unit(y), state.get_content(a)),
//_ => Box::
//})
//}
fn get_bool (&self, _sym: &str) -> bool { false }
fn get_unit (&self, _sym: &str) -> E::Unit { 0.into() }
fn get_usize (&self, _sym: &str) -> usize { 0 }
fn get_content (&'a self, _sym: &str) -> Box<EdnRender<'a, E>> { Box::new(()) }
}

View file

@ -1,8 +1,5 @@
use crate::*;
use std::marker::PhantomData;
use EdnItem::*;
use EdnItem::*;
/// Renders from EDN source and context.
pub struct EdnView<'a, E: Engine + 'a, T: EdnLayout<'a, E> + 'a> {
@ -15,9 +12,53 @@ pub struct EdnView<'a, E: Engine + 'a, T: EdnLayout<'a, E> + 'a> {
impl<'a, E: Engine + 'a, T: EdnLayout<'a, E> + 'a> EdnView<'a, E, T> {
pub fn new (context: T, source: &'a str) -> Usually<Self> {
let layout = EdnItem::read_one(&source)?.0;
for symbol in layout.symbols() {
context.import(symbol)
}
Ok(Self { _engine: Default::default(), context, layout, })
}
}
impl<'a, E: Engine + 'a, T: EdnLayout<'a, E> + Send + Sync + 'a> Content<E> for EdnView<'a, E, T> {
fn content (&self) -> impl Render<E> {
use EdnItem::*;
match &self.layout {
Nil => None,
Sym(t) => Some(self.context.get_content(t.as_str())),
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) => todo!("exp {e:?}"),
}
//let items = &self.layout;
//if let (Some(first), rest) = (items.get(0).map(EdnItem::to_str), &items[1..]) {
//match (first, rest) {
//("when", [c, a, ..]) => Box::new(move|state|Box::new(
//When(state.get_bool(&c.to_ref()), state.get_content(&a.to_ref())))),
//_ => Box::new(|_|Box::new(()))
//}
//} else {
//Box::new(|_|Box::new(()))
//}
}
//Box::new(match [items.get(0).map(|x|x.to_str()), items[1..]] {
//["when", [c, a, ..]] => When(state.get_bool(c), state.get_content(a)),
//["either", [c, a, b, ..]] => Either(state.get_bool(c), state.get_content(a), state.get_content(b)),
//["fill", [a, ..]] => Fill::xy(state.get_content(a)),
//["fill/x", [a, ..]] => Fill::x(state.get_content(a)),
//["fill/y", [a, ..]] => Fill::y(state.get_content(a)),
//["fixed", [x, y, a, ..]] => Fixed::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
//["fixed/x", [x, a, ..]] => Fixed::x(state.get_unit(x), state.get_content(a)),
//["fixed/y", [y, a, ..]] => Fixed::y(state.get_unit(y), state.get_content(a)),
//["shrink", [x, y, a, ..]] => Shrink::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
//["shrink/x", [x, a, ..]] => Shrink::x(state.get_unit(x), state.get_content(a)),
//["shrink/y", [y, a, ..]] => Shrink::y(state.get_unit(y), state.get_content(a)),
//["expand", [x, y, a, ..]] => Expand::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
//["expand/x", [x, a, ..]] => Expand::x(state.get_unit(x), state.get_content(a)),
//["expand/y", [y, a, ..]] => Expand::y(state.get_unit(y), state.get_content(a)),
//["push", [x, y, a, ..]] => Push::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
//["push/x", [x, a, ..]] => Push::x(state.get_unit(x), state.get_content(a)),
//["push/y", [y, a, ..]] => Push::y(state.get_unit(y), state.get_content(a)),
//["pull", [x, y, a, ..]] => Pull::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
//["pull/x", [x, a, ..]] => Pull::x(state.get_unit(x), state.get_content(a)),
//["pull/y", [y, a, ..]] => Pull::y(state.get_unit(y), state.get_content(a)),
//_ => Box::
//})
//}
}

View file

@ -1,7 +1,13 @@
#![feature(type_alias_impl_trait)]
#![feature(impl_trait_in_fn_trait_return)]
pub(crate) use ::tek_layout::{*, tek_engine::{Usually, Content, Render, Engine, Thunk}};
pub(crate) use std::{
fmt::{Debug, Formatter, Error as FormatError}
};
pub(crate) use ::tek_layout::{
*,
tek_engine::{Usually, Content, Render, Engine, Thunk}
};
mod edn_error; pub use self::edn_error::*;
mod edn_item; pub use self::edn_item::*;