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

14
edn/Cargo.lock generated
View file

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

View file

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

View file

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

View file

@ -13,43 +13,8 @@ pub type EdnRenderCallback<'a, Engine, State> =
Box<EdnCallback<'a, Engine, State>>; Box<EdnCallback<'a, Engine, State>>;
pub trait EdnLayout<'a, E: Engine + 'a> where Self: 'a { pub trait EdnLayout<'a, E: Engine + 'a> where Self: 'a {
fn get_bool (&self, _: &EdnItem<&str>) -> bool { false } fn get_bool (&self, _sym: &str) -> bool { false }
fn get_unit (&self, _: &EdnItem<&str>) -> E::Unit { 0.into() } fn get_unit (&self, _sym: &str) -> E::Unit { 0.into() }
fn get_usize (&self, _: &EdnItem<&str>) -> usize { 0 } fn get_usize (&self, _sym: &str) -> usize { 0 }
fn get_content (&'a self, _: &EdnItem<&str>) -> Box<EdnRender<'a, E>> { Box::new(()) } fn get_content (&'a self, _sym: &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::
//})
//}
} }

View file

@ -1,8 +1,5 @@
use crate::*; use crate::*;
use std::marker::PhantomData; use std::marker::PhantomData;
use EdnItem::*;
use EdnItem::*;
/// Renders from EDN source and context. /// Renders from EDN source and context.
pub struct EdnView<'a, E: Engine + 'a, T: EdnLayout<'a, E> + 'a> { 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> { impl<'a, E: Engine + 'a, T: EdnLayout<'a, E> + 'a> EdnView<'a, E, T> {
pub fn new (context: T, source: &'a str) -> Usually<Self> { pub fn new (context: T, source: &'a str) -> Usually<Self> {
let layout = EdnItem::read_one(&source)?.0; let layout = EdnItem::read_one(&source)?.0;
for symbol in layout.symbols() {
context.import(symbol)
}
Ok(Self { _engine: Default::default(), context, layout, }) 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(type_alias_impl_trait)]
#![feature(impl_trait_in_fn_trait_return)] #![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_error; pub use self::edn_error::*;
mod edn_item; pub use self::edn_item::*; mod edn_item; pub use self::edn_item::*;