From 433e4df0f29bce814766a284893c2b3327cb1cca Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sun, 5 Jan 2025 04:07:27 +0100 Subject: [PATCH] wip: still trying to write the iterator --- Cargo.lock | 14 ++++++++++-- edn/Cargo.lock | 14 ++++++++++-- edn/Cargo.toml | 1 + edn/src/edn_item.rs | 47 +++++++++++++++++++++++++------------- edn/src/edn_layout.rs | 43 ++++------------------------------- edn/src/edn_view.rs | 53 ++++++++++++++++++++++++++++++++++++++----- edn/src/lib.rs | 8 ++++++- 7 files changed, 114 insertions(+), 66 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aa24f594..5befacd0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", ] diff --git a/edn/Cargo.lock b/edn/Cargo.lock index fa4411ba..6c6ca5a3 100644 --- a/edn/Cargo.lock +++ b/edn/Cargo.lock @@ -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", ] diff --git a/edn/Cargo.toml b/edn/Cargo.toml index d07d4640..0d09a35e 100644 --- a/edn/Cargo.toml +++ b/edn/Cargo.toml @@ -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] diff --git a/edn/src/edn_item.rs b/edn/src/edn_item.rs index f7091d8a..a2c8e874 100644 --- a/edn/src/edn_item.rs +++ b/edn/src/edn_item.rs @@ -12,6 +12,19 @@ impl Default for EdnItem { Self::Nil } } +impl Debug for EdnItem { + 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 + PartialEq + Default + Clone + std::fmt::Debug> EdnItem { pub fn to_ref (&self) -> EdnItem<&str> { match self { @@ -25,40 +38,42 @@ impl + PartialEq + Default + Clone + std::fmt::Debug> EdnItem { _ => 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]) + Exp(Vec>) } -impl<'a, T: AsRef> SymIterator<'a, T> { +impl<'a, T: AsRef> EdnIterator<'a, T> { fn new (item: &'a EdnItem) -> 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> Iterator for SymIterator<'a, T> { - type Item = &'a str; +impl<'a, T: AsRef> Iterator for EdnIterator<'a, T> { + type Item = &'a T; fn next (&mut self) -> Option { - 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 diff --git a/edn/src/edn_layout.rs b/edn/src/edn_layout.rs index e5156ba1..6c893626 100644 --- a/edn/src/edn_layout.rs +++ b/edn/src/edn_layout.rs @@ -13,43 +13,8 @@ pub type EdnRenderCallback<'a, Engine, State> = Box>; 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> { Box::new(()) } - fn parse (items: &'a [EdnItem]) -> 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> { Box::new(()) } } diff --git a/edn/src/edn_view.rs b/edn/src/edn_view.rs index a005d0ca..dbac002b 100644 --- a/edn/src/edn_view.rs +++ b/edn/src/edn_view.rs @@ -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 { 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 for EdnView<'a, E, T> { + fn content (&self) -> impl Render { + 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:: + //}) + //} +} diff --git a/edn/src/lib.rs b/edn/src/lib.rs index bcd2033f..70f8ced2 100644 --- a/edn/src/lib.rs +++ b/edn/src/lib.rs @@ -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::*;