From b0d2fad17beef84be8f1fdad116643563379a2c1 Mon Sep 17 00:00:00 2001 From: AAAAAAAAAAAAAAAAAAAAAAAAAAAA Date: Sat, 17 Jan 2026 01:12:33 +0200 Subject: [PATCH 1/3] fix(bsp, event): pub; don't panic --- output/src/layout/layout_bsp.rs | 4 ++-- tui/src/tui_engine/tui_event.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/output/src/layout/layout_bsp.rs b/output/src/layout/layout_bsp.rs index 3de4cfc..bd65e96 100644 --- a/output/src/layout/layout_bsp.rs +++ b/output/src/layout/layout_bsp.rs @@ -22,7 +22,7 @@ impl, Tail: Content> Draw for Bsp { fn draw (&self, to: &mut O) { match self.0 { South => { - panic!("{}", self.1.h(to.area())); + //panic!("{}", self.1.h(to.area())); let area_1 = self.1.layout(to.area()); let area_2 = self.2.layout([ to.area().x(), @@ -30,7 +30,7 @@ impl, Tail: Content> Draw for Bsp { to.area().w(), to.area().h().minus(area_1.h()) ].into()); - panic!("{area_1:?} {area_2:?}"); + //panic!("{area_1:?} {area_2:?}"); to.place_at(area_1, &self.1); to.place_at(area_2, &self.2); }, diff --git a/tui/src/tui_engine/tui_event.rs b/tui/src/tui_engine/tui_event.rs index dbc0a98..1245a30 100644 --- a/tui/src/tui_engine/tui_event.rs +++ b/tui/src/tui_engine/tui_event.rs @@ -1,5 +1,5 @@ use crate::*; -#[derive(Debug, Clone, Eq, PartialEq, PartialOrd)] pub struct TuiEvent(Event); +#[derive(Debug, Clone, Eq, PartialEq, PartialOrd)] pub struct TuiEvent(pub Event); impl Ord for TuiEvent { fn cmp (&self, other: &Self) -> std::cmp::Ordering { self.partial_cmp(other) From 1344967f33ac8c8e87ff8585fe8b463a15f088f7 Mon Sep 17 00:00:00 2001 From: AAAAAAAAAAAAAAAAAAAAAAAAAAAA Date: Sat, 17 Jan 2026 03:43:27 +0200 Subject: [PATCH 2/3] refactor: extract dizzle --- Cargo.lock | 42 +- Cargo.toml | 10 +- core/Cargo.toml | 6 - core/src/core_macros.rs | 137 ---- core/src/lib.rs | 45 -- dsl/Cargo.lock | 980 ----------------------------- dsl/Cargo.toml | 19 - dsl/README.md | 68 -- dsl/proptest-regressions/iter.txt | 7 - dsl/proptest-regressions/token.txt | 7 - dsl/src/dsl.rs | 227 ------- dsl/src/dsl_error.rs | 25 - dsl/src/dsl_expr.rs | 87 --- dsl/src/dsl_ns.rs | 46 -- dsl/src/dsl_test.rs | 99 --- dsl/src/dsl_text.rs | 20 - dsl/src/dsl_word.rs | 49 -- dsl/test.edn | 1 - editor/Cargo.toml | 5 - editor/src/main.rs | 0 input/Cargo.toml | 3 +- input/input.rs | 2 +- output/Cargo.toml | 11 +- output/src/lib.rs | 200 ++++++ output/src/output.rs | 33 +- output/src/output_test.rs | 170 ----- output/src/view.rs | 2 +- proc/Cargo.toml | 2 +- tengri/Cargo.toml | 15 +- tengri/src/lib.rs | 110 +++- tengri/src/test.rs | 103 --- tui/Cargo.toml | 11 +- tui/src/lib.rs | 29 + tui/src/tui.rs | 36 +- 34 files changed, 372 insertions(+), 2235 deletions(-) delete mode 100644 core/Cargo.toml delete mode 100644 core/src/core_macros.rs delete mode 100644 core/src/lib.rs delete mode 100644 dsl/Cargo.lock delete mode 100644 dsl/Cargo.toml delete mode 100644 dsl/README.md delete mode 100644 dsl/proptest-regressions/iter.txt delete mode 100644 dsl/proptest-regressions/token.txt delete mode 100644 dsl/src/dsl.rs delete mode 100644 dsl/src/dsl_error.rs delete mode 100644 dsl/src/dsl_expr.rs delete mode 100644 dsl/src/dsl_ns.rs delete mode 100644 dsl/src/dsl_test.rs delete mode 100644 dsl/src/dsl_text.rs delete mode 100644 dsl/src/dsl_word.rs delete mode 100644 dsl/test.edn delete mode 100644 editor/Cargo.toml delete mode 100644 editor/src/main.rs create mode 100644 output/src/lib.rs delete mode 100644 output/src/output_test.rs delete mode 100644 tengri/src/test.rs create mode 100644 tui/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index e5500fc..6d96025 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -285,6 +285,16 @@ dependencies = [ "syn", ] +[[package]] +name = "dizzle" +version = "0.1.0" +dependencies = [ + "const_panic", + "itertools 0.14.0", + "konst", + "thiserror", +] + [[package]] name = "document-features" version = "0.2.11" @@ -1045,38 +1055,19 @@ name = "tengri" version = "0.14.0" dependencies = [ "crossterm 0.29.0", + "dizzle", "tengri", - "tengri_core", - "tengri_dsl", "tengri_input", "tengri_output", "tengri_proc", "tengri_tui", ] -[[package]] -name = "tengri_core" -version = "0.14.0" - -[[package]] -name = "tengri_dsl" -version = "0.14.0" -dependencies = [ - "const_panic", - "itertools 0.14.0", - "konst", - "proptest", - "tengri_core", - "tengri_tui", - "thiserror", -] - [[package]] name = "tengri_input" version = "0.14.0" dependencies = [ - "tengri_core", - "tengri_dsl", + "dizzle", "tengri_tui", ] @@ -1085,11 +1076,10 @@ name = "tengri_output" version = "0.14.0" dependencies = [ "bumpalo", + "dizzle", "proptest", "proptest-derive", "tengri", - "tengri_core", - "tengri_dsl", "tengri_tui", ] @@ -1097,11 +1087,11 @@ dependencies = [ name = "tengri_proc" version = "0.14.0" dependencies = [ + "dizzle", "heck", "proc-macro2", "quote", "syn", - "tengri_core", ] [[package]] @@ -1112,14 +1102,12 @@ dependencies = [ "better-panic", "bumpalo", "crossterm 0.29.0", - "konst", + "dizzle", "palette", "quanta", "rand 0.8.5", "ratatui", "tengri", - "tengri_core", - "tengri_dsl", "tengri_input", "tengri_output", "tengri_proc", diff --git a/Cargo.toml b/Cargo.toml index f2280f9..7619d5c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,11 +9,9 @@ lto = false resolver = "2" members = [ "./tengri", - "./core", "./input", "./output", "./tui", - "./dsl", "./proc", ] @@ -22,23 +20,20 @@ version = "0.14.0" edition = "2024" [workspace.dependencies] +dizzle = { path = "../dizzle" } + tengri = { path = "./tengri" } -tengri_core = { path = "./core" } tengri_input = { path = "./input" } tengri_output = { path = "./output" } tengri_tui = { path = "./tui" } -tengri_dsl = { path = "./dsl" } tengri_proc = { path = "./proc" } anyhow = { version = "1.0" } atomic_float = { version = "1" } better-panic = { version = "0.3.0" } bumpalo = { version = "3.19.0" } -const_panic = { version = "0.2.12", features = [ "derive" ] } crossterm = { version = "0.29.0" } heck = { version = "0.5" } -itertools = { version = "0.14.0" } -konst = { version = "0.3.16", features = [ "rust_1_83" ] } palette = { version = "0.7.6", features = [ "random" ] } proc-macro2 = { version = "1", features = ["span-locations"] } proptest = { version = "^1" } @@ -48,5 +43,4 @@ quote = { version = "1" } rand = { version = "0.8.5" } ratatui = { version = "0.29.0", features = [ "unstable-widget-ref", "underline-color" ] } syn = { version = "2", features = ["full", "extra-traits"] } -thiserror = { version = "2.0" } unicode-width = { version = "0.2" } diff --git a/core/Cargo.toml b/core/Cargo.toml deleted file mode 100644 index b4e9baa..0000000 --- a/core/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "tengri_core" -description = "UI metaframework, core definitions." -version = { workspace = true } -edition = { workspace = true } - diff --git a/core/src/core_macros.rs b/core/src/core_macros.rs deleted file mode 100644 index ef56421..0000000 --- a/core/src/core_macros.rs +++ /dev/null @@ -1,137 +0,0 @@ -/// Define and reexport submodules. -#[macro_export] macro_rules! modules( - ($($($feat:literal?)? $name:ident),* $(,)?) => { $( - $(#[cfg(feature=$feat)])? mod $name; - $(#[cfg(feature=$feat)])? pub use self::$name::*; - )* }; - ($($($feat:literal?)? $name:ident $body:block),* $(,)?) => { $( - $(#[cfg(feature=$feat)])? mod $name $body - $(#[cfg(feature=$feat)])? pub use self::$name::*; - )* }; -); - -/// Define a trait and implement it for read-only wrapper types. -#[macro_export] macro_rules! flex_trait ( - ($Trait:ident $(<$($A:ident:$T:ident),+>)? $(:$dep:ident $(<$dtt:tt>)? $(+$dep2:ident $(<$dtt2:tt>)?)*)? { - $(fn $fn:ident $(<$($fl:lifetime),*>)? (& $($fl2:lifetime)* $self:ident $(, $arg:ident:$ty:ty)*) $(-> $ret:ty)? $body:block)* - }) => { - pub trait $Trait $(<$($A: $T),+>)? $(:$dep $(<$dtt>)? $(+$dep2 $(<$dtt2>)?)*)? { - $(fn $fn $(<$($fl),*>)? (& $($fl2)* $self $(,$arg:$ty)*) $(-> $ret)? $body)* - } - impl<$($($A: $T,)+)? _T_: $Trait $(<$($A),+>)?> $Trait $(<$($A),+>)? for &_T_ { - $(fn $fn $(<$($fl),*>)? (& $($fl2)* $self $(,$arg:$ty)*) $(-> $ret)? { (*$self).$fn($($arg),*) })* - } - impl<$($($A: $T,)+)? _T_: $Trait $(<$($A),+>)?> $Trait $(<$($A),+>)? for &mut _T_ { - $(fn $fn $(<$($fl),*>)? (& $($fl2)* $self $(,$arg:$ty)*) $(-> $ret)? { (**$self).$fn($($arg),*) })* - } - impl<$($($A: $T,)+)? _T_: $Trait $(<$($A),+>)?> $Trait $(<$($A),+>)? for ::std::sync::Arc<_T_> { - $(fn $fn $(<$($fl),*>)? (& $($fl2)* $self $(,$arg:$ty)*) $(-> $ret)? { (*$self).$fn($($arg),*) })* - } - impl<$($($A: $T,)+)?> $Trait $(<$($A),+>)? for Box)?> { - $(fn $fn $(<$($fl),*>)? (& $($fl2)* $self $(,$arg:$ty)*) $(-> $ret)? { (**$self).$fn($($arg),*) })* - } - //impl<$($($A: $T,)+)? _T_: $Trait $(<$($A),+>)?> $Trait $(<$($A),+>)? for Option<_T_> { - //$(fn $fn (&$self $(,$arg:$ty)*) -> $ret { - //if let Some(this) = $self { this.$fn($($arg),*) } else { Ok(None) } - //})* - //} - //impl<$($($A: $T,)+)? _T_: $Trait $(<$($A),+>)?> $Trait $(<$($A),+>)? for ::std::sync::Mutex<_T_> { - //$(fn $fn (&$self $(,$arg:$ty)*) -> $ret { (*$self).lock().unwrap().$fn($($arg),*) })* - //} - //impl<$($($A: $T,)+)? _T_: $Trait $(<$($A),+>)?> $Trait $(<$($A),+>)? for ::std::sync::RwLock<_T_> { - //$(fn $fn (&$self $(,$arg:$ty)*) -> $ret { $self.read().unwrap().$fn($($arg),*) })* - //} - }); -/// Define a trait an implement it for read-only wrapper types. */ -#[macro_export] macro_rules! flex_trait_sized ( - ($Trait:ident $(<$($A:ident:$T:ident),+>)? $(:$dep:ident $(<$dtt:tt>)? $(+$dep2:ident $(<$dtt2:tt>)?)*)? { - $(fn $fn:ident (&$self:ident $(, $arg:ident:$ty:ty)*) $(-> $ret:ty)? $body:block)* - }) => { - pub trait $Trait $(<$($A: $T),+>)? : $($dep $(<$dtt>+)? $($dep2 $(<$dtt2>)?)*+)? Sized { - $(fn $fn (&$self $(,$arg:$ty)*) $(-> $ret)? $body)* - } - impl<$($($A: $T,)+)? _T_: $Trait $(<$($A),+>)?> $Trait $(<$($A),+>)? for &_T_ { - $(fn $fn (&$self $(,$arg:$ty)*) $(-> $ret)? { (*$self).$fn($($arg),*) })* - } - impl<$($($A: $T,)+)? _T_: $Trait $(<$($A),+>)?> $Trait $(<$($A),+>)? for &mut _T_ { - $(fn $fn (&$self $(,$arg:$ty)*) $(-> $ret)? { (**$self).$fn($($arg),*) })* - } - impl<$($($A: $T,)+)? _T_: $Trait $(<$($A),+>)?> $Trait $(<$($A),+>)? for ::std::sync::Arc<_T_> { - $(fn $fn (&$self $(,$arg:$ty)*) $(-> $ret)? { (*$self).$fn($($arg),*) })* - } - impl<$($($A: $T,)+)?> $Trait $(<$($A),+>)? for Box)?> { - $(fn $fn (&$self $(,$arg:$ty)*) $(-> $ret)? { (**$self).$fn($($arg),*) })* - } - //impl<$($($A: $T,)+)? _T_: $Trait $(<$($A),+>)?> $Trait $(<$($A),+>)? for Option<_T_> { - //$(fn $fn (&$self $(,$arg:$ty)*) -> $ret { - //if let Some(this) = $self { this.$fn($($arg),*) } else { Ok(None) } - //})* - //} - //impl<$($($A: $T,)+)? _T_: $Trait $(<$($A),+>)?> $Trait $(<$($A),+>)? for ::std::sync::Mutex<_T_> { - //$(fn $fn (&$self $(,$arg:$ty)*) -> $ret { (*$self).lock().unwrap().$fn($($arg),*) })* - //} - //impl<$($($A: $T,)+)? _T_: $Trait $(<$($A),+>)?> $Trait $(<$($A),+>)? for ::std::sync::RwLock<_T_> { - //$(fn $fn (&$self $(,$arg:$ty)*) -> $ret { $self.read().unwrap().$fn($($arg),*) })* - //} - }); - -/// Define a trait an implement it for various mutation-enabled wrapper types. */ -#[macro_export] macro_rules! flex_trait_mut ( - ($Trait:ident $(<$($A:ident:$T:ident),+>)? { - $(fn $fn:ident (&mut $self:ident $(, $arg:ident:$ty:ty)*) -> $ret:ty $body:block)* - })=>{ - pub trait $Trait $(<$($A: $T),+>)? { - $(fn $fn (&mut $self $(,$arg:$ty)*) -> $ret $body)* - } - impl<$($($A: $T,)+)? _T_: $Trait $(<$($A),+>)?> $Trait $(<$($A),+>)? for &mut _T_ { - $(fn $fn (&mut $self $(,$arg:$ty)*) -> $ret { (*$self).$fn($($arg),*) })* - } - impl<$($($A: $T,)+)? _T_: $Trait $(<$($A),+>)?> $Trait $(<$($A),+>)? for Option<_T_> { - $(fn $fn (&mut $self $(,$arg:$ty)*) -> $ret { - if let Some(this) = $self { this.$fn($($arg),*) } else { Ok(None) } - })* - } - impl<$($($A: $T,)+)? _T_: $Trait $(<$($A),+>)?> $Trait $(<$($A),+>)? for ::std::sync::Mutex<_T_> { - $(fn $fn (&mut $self $(,$arg:$ty)*) -> $ret { $self.get_mut().unwrap().$fn($($arg),*) })* - } - impl<$($($A: $T,)+)? _T_: $Trait $(<$($A),+>)?> $Trait $(<$($A),+>)? for ::std::sync::Arc<::std::sync::Mutex<_T_>> { - $(fn $fn (&mut $self $(,$arg:$ty)*) -> $ret { $self.lock().unwrap().$fn($($arg),*) })* - } - impl<$($($A: $T,)+)? _T_: $Trait $(<$($A),+>)?> $Trait $(<$($A),+>)? for ::std::sync::RwLock<_T_> { - $(fn $fn (&mut $self $(,$arg:$ty)*) -> $ret { $self.write().unwrap().$fn($($arg),*) })* - } - impl<$($($A: $T,)+)? _T_: $Trait $(<$($A),+>)?> $Trait $(<$($A),+>)? for ::std::sync::Arc<::std::sync::RwLock<_T_>> { - $(fn $fn (&mut $self $(,$arg:$ty)*) -> $ret { $self.write().unwrap().$fn($($arg),*) })* - } - }; -); - -/// Implement [`Debug`] in bulk. -#[macro_export] macro_rules! impl_debug(($($S:ty|$self:ident,$w:ident|$body:block)*)=>{ - $(impl std::fmt::Debug for $S { - fn fmt (&$self, $w: &mut std::fmt::Formatter) -> std::fmt::Result $body - })* }); - -/// Implement [`From`] in bulk. -#[macro_export] macro_rules! from( - ($(<$($lt:lifetime),+>)?|$state:ident:$Source:ty|$Target:ty=$cb:expr) => { - impl $(<$($lt),+>)? From<$Source> for $Target { - fn from ($state:$Source) -> Self { $cb }}}; - ($($Struct:ty { $( - $(<$($l:lifetime),* $($T:ident$(:$U:ident)?),*>)? ($source:ident: $From:ty) $expr:expr - );+ $(;)? })*) => { $( - $(impl $(<$($l),* $($T$(:$U)?),*>)? From<$From> for $Struct { - fn from ($source: $From) -> Self { $expr } })+ )* }; ); - -/// Implement [Has]. -#[macro_export] macro_rules! has(($T:ty: |$self:ident : $S:ty| $x:expr) => { - impl Has<$T> for $S { - fn get (&$self) -> &$T { &$x } - fn get_mut (&mut $self) -> &mut $T { &mut $x } } };); - -/// Implement [MaybeHas]. -#[macro_export] macro_rules! maybe_has( - ($T:ty: |$self:ident : $S:ty| $x:block; $y:block $(;)?) => { - impl MaybeHas<$T> for $S { - fn get (&$self) -> Option<&$T> $x - fn get_mut (&mut $self) -> Option<&mut $T> $y } };); diff --git a/core/src/lib.rs b/core/src/lib.rs deleted file mode 100644 index 7bf320e..0000000 --- a/core/src/lib.rs +++ /dev/null @@ -1,45 +0,0 @@ -mod core_macros; -pub(crate) use std::error::Error; - -/// Standard result type. -pub type Usually = Result>; - -/// Standard optional result type. -pub type Perhaps = Result, Box>; - -/// Type-dispatched `get` and `get_mut`. -pub trait Has: Send + Sync { fn get (&self) -> &T; fn get_mut (&mut self) -> &mut T; } - -/// Type-dispatched `get` and `get_mut` that return an [Option]-wrapped result. -pub trait MaybeHas: Send + Sync { fn get (&self) -> Option<&T>; fn get_mut (&mut self) -> Option<&mut T>; } - -/// May compute a `RetVal` from `Args`. -pub trait Eval { - /// A custom operation on [Args] that may return [Result::Err] or [Option::None]. - fn try_eval (&self, args: &Args) -> Perhaps; - /// Invoke a custom operation, converting a `None` result to a custom `Box`. - fn eval >> (&self, args: &Args, error: impl Fn()->E) - -> Usually - { - match self.try_eval(args)? { - Some(value) => Ok(value), - _ => Result::Err(format!("Eval: {}", error().into()).into()) - } - } -} - -#[macro_export] macro_rules! as_ref { - ($T:ty: |$self:ident : $S:ty| $x:expr) => { - impl AsRef<$T> for $S { - fn as_ref (&$self) -> &$T { &$x } - } - }; -} - -pub fn wrap_inc (index: usize, count: usize) -> usize { - if count > 0 { (index + 1) % count } else { 0 } -} - -pub fn wrap_dec (index: usize, count: usize) -> usize { - if count > 0 { index.overflowing_sub(1).0.min(count.saturating_sub(1)) } else { 0 } -} diff --git a/dsl/Cargo.lock b/dsl/Cargo.lock deleted file mode 100644 index 26585b0..0000000 --- a/dsl/Cargo.lock +++ /dev/null @@ -1,980 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - -[[package]] -name = "approx" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" -dependencies = [ - "num-traits", -] - -[[package]] -name = "autocfg" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" - -[[package]] -name = "backtrace" -version = "0.3.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets", -] - -[[package]] -name = "better-panic" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fa9e1d11a268684cbd90ed36370d7577afb6c62d912ddff5c15fc34343e5036" -dependencies = [ - "backtrace", - "console", -] - -[[package]] -name = "bitflags" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" - -[[package]] -name = "by_address" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "cassowary" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" - -[[package]] -name = "castaway" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0abae9be0aaf9ea96a3b1b8b1b55c602ca751eba1b1500220cea4ecbafe7c0d5" -dependencies = [ - "rustversion", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "clojure-reader" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edf141eea627c101a97509266bc9f6ba8cd408618f5e2ac4a0cb6b64b1d4ea8" -dependencies = [ - "ordered-float", -] - -[[package]] -name = "compact_str" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b79c4069c6cad78e2e0cdfcbd26275770669fb39fd308a752dc110e83b9af32" -dependencies = [ - "castaway", - "cfg-if", - "itoa", - "rustversion", - "ryu", - "static_assertions", -] - -[[package]] -name = "console" -version = "0.15.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea3c6ecd8059b57859df5c69830340ed3c41d30e3da0c1cbed90a96ac853041b" -dependencies = [ - "encode_unicode", - "libc", - "once_cell", - "windows-sys 0.59.0", -] - -[[package]] -name = "const_panic" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53857514f72ee4a2b583de67401e3ff63a5472ca4acf289d09a9ea7636dfec17" - -[[package]] -name = "crossterm" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" -dependencies = [ - "bitflags", - "crossterm_winapi", - "mio", - "parking_lot", - "rustix", - "signal-hook", - "signal-hook-mio", - "winapi", -] - -[[package]] -name = "crossterm_winapi" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" -dependencies = [ - "winapi", -] - -[[package]] -name = "darling" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn", -] - -[[package]] -name = "darling_macro" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" -dependencies = [ - "darling_core", - "quote", - "syn", -] - -[[package]] -name = "either" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - -[[package]] -name = "encode_unicode" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "errno" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - -[[package]] -name = "fast-srgb8" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foldhash" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - -[[package]] -name = "hashbrown" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" -dependencies = [ - "allocator-api2", - "equivalent", - "foldhash", -] - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "indoc" -version = "2.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" - -[[package]] -name = "instability" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "894813a444908c0c8c0e221b041771d107c4a21de1d317dc49bcc66e3c9e5b3f" -dependencies = [ - "darling", - "indoc", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" - -[[package]] -name = "konst" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4381b9b00c55f251f2ebe9473aef7c117e96828def1a7cb3bd3f0f903c6894e9" -dependencies = [ - "const_panic", - "konst_kernel", - "konst_proc_macros", - "typewit", -] - -[[package]] -name = "konst_kernel" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4b1eb7788f3824c629b1116a7a9060d6e898c358ebff59070093d51103dcc3c" -dependencies = [ - "typewit", -] - -[[package]] -name = "konst_proc_macros" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00af7901ba50898c9e545c24d5c580c96a982298134e8037d8978b6594782c07" - -[[package]] -name = "libc" -version = "0.2.169" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" - -[[package]] -name = "linux-raw-sys" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" - -[[package]] -name = "lock_api" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" - -[[package]] -name = "lru" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" -dependencies = [ - "hashbrown", -] - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "miniz_oxide" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" -dependencies = [ - "adler2", -] - -[[package]] -name = "mio" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" -dependencies = [ - "libc", - "log", - "wasi", - "windows-sys 0.52.0", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" - -[[package]] -name = "ordered-float" -version = "4.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" -dependencies = [ - "num-traits", -] - -[[package]] -name = "palette" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cbf71184cc5ecc2e4e1baccdb21026c20e5fc3dcf63028a086131b3ab00b6e6" -dependencies = [ - "approx", - "fast-srgb8", - "palette_derive", - "phf", - "rand", -] - -[[package]] -name = "palette_derive" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5030daf005bface118c096f510ffb781fc28f9ab6a32ab224d8631be6851d30" -dependencies = [ - "by_address", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "parking_lot" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "phf" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" -dependencies = [ - "phf_macros", - "phf_shared", -] - -[[package]] -name = "phf_generator" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" -dependencies = [ - "phf_shared", - "rand", -] - -[[package]] -name = "phf_macros" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" -dependencies = [ - "phf_generator", - "phf_shared", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "phf_shared" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" -dependencies = [ - "siphasher", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "proc-macro2" -version = "1.0.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "ratatui" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b" -dependencies = [ - "bitflags", - "cassowary", - "compact_str", - "crossterm", - "indoc", - "instability", - "itertools 0.13.0", - "lru", - "paste", - "strum", - "unicode-segmentation", - "unicode-truncate", - "unicode-width 0.2.0", -] - -[[package]] -name = "redox_syscall" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" -dependencies = [ - "bitflags", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustix" -version = "0.38.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.59.0", -] - -[[package]] -name = "rustversion" -version = "1.0.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "signal-hook" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" -dependencies = [ - "libc", - "signal-hook-registry", -] - -[[package]] -name = "signal-hook-mio" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" -dependencies = [ - "libc", - "mio", - "signal-hook", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" -dependencies = [ - "libc", -] - -[[package]] -name = "siphasher" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" - -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "strum" -version = "0.26.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn", -] - -[[package]] -name = "syn" -version = "2.0.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tengri_dsl" -version = "0.1.0" -dependencies = [ - "clojure-reader", - "itertools 0.14.0", - "konst", - "tengri_tui", -] - -[[package]] -name = "tengri_input" -version = "0.2.0" - -[[package]] -name = "tengri_output" -version = "0.2.0" -dependencies = [ - "tengri_dsl", -] - -[[package]] -name = "tengri_tui" -version = "0.2.0" -dependencies = [ - "better-panic", - "crossterm", - "palette", - "rand", - "ratatui", - "tengri_dsl", - "tengri_input", - "tengri_output", -] - -[[package]] -name = "typewit" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb77c29baba9e4d3a6182d51fa75e3215c7fd1dab8f4ea9d107c716878e55fc0" -dependencies = [ - "typewit_proc_macros", -] - -[[package]] -name = "typewit_proc_macros" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36a83ea2b3c704935a01b4642946aadd445cea40b10935e3f8bd8052b8193d6" - -[[package]] -name = "unicode-ident" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" - -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - -[[package]] -name = "unicode-truncate" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf" -dependencies = [ - "itertools 0.13.0", - "unicode-segmentation", - "unicode-width 0.1.14", -] - -[[package]] -name = "unicode-width" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" - -[[package]] -name = "unicode-width" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/dsl/Cargo.toml b/dsl/Cargo.toml deleted file mode 100644 index c61a057..0000000 --- a/dsl/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "tengri_dsl" -description = "UI metaframework, tiny S-expression-based DSL." -version = { workspace = true } -edition = { workspace = true } - -[lib] -path = "src/dsl.rs" - -[dependencies] -tengri_core = { path = "../core" } -konst = { workspace = true } -const_panic = { workspace = true } -itertools = { workspace = true } -thiserror = { workspace = true } - -[dev-dependencies] -tengri_tui = { path = "../tui" } -proptest = "^1.6.0" diff --git a/dsl/README.md b/dsl/README.md deleted file mode 100644 index 0ef496d..0000000 --- a/dsl/README.md +++ /dev/null @@ -1,68 +0,0 @@ -[***dizzle***](https://codeberg.org/unspeaker/tengri/src/branch/main/dsl) -is a means of adding a tiny interpreted domain-specific language to your programs. - -dizzle currently provides an s-expression based syntax. - -dizzle parses source code by means of the `Dsl`, `DslExpr` and `DslWord` traits. -those are implemented for basic stringy types and their `Option` and `Result` wrapped analogs. -to customize parsing, define and use your own traits on top of the provided ones. - -dizzle evaluates the parsed source code by means of the `DslNs` trait. the methods of -this trait match literals, words, and expressions, against pre-defined lists. the -`dsl_words` and `dsl_exprs` macros let you define those lists slightly less verbosely. - -## goals - -* [x] const parse -* [ ] live reload -* [ ] serialize modified code back to original indentation - -## examples - -### in [`tengri_output`](../output) - -```edn -(bsp/s (fixed/y 2 :toolbar) - (fill/x (align/c (bsp/w :pool - (bsp/s :outputs (bsp/s :inputs (bsp/s :tracks :scenes))))))) -``` - -### in [`tengri_input`](../input) - -```edn -(@u undo 1) -(@shift-u redo 1) -(@e editor show :pool-clip) -(@ctrl-a scene add) -(@ctrl-t track add) -(@tab pool toggle) -``` - -## implementation notes - -### `DslExpr` trait behavior - -this is the trait which differentiates "a thing" from -"a thing that is many things". - -|source |key|exp |head |tail | -|---------------|---|-------|---------|---------------| -|`a` |`a`|e0 |`a` |None | -|`(a)` |e1 |`a` |`(a)` |None | -|`a b c` |e2 |e0 |`a` |`b c` | -|`(a b c)` |e1 |`a b c`|`(a b c)`| | -|`(a b c) d e` |e1 |e3 |`(a b c)`|`d e` | -|`a (b c d) e f`|e1 |e0 |`a` |`(b c d) e f` | - -* e0: Unexpected 'a' -* e1: Unexpected '(' -* e2: Unexpected 'b' -* e3: Unexpected 'd' - -### possible design for operator-based syntax - -* replace: `(:= :name :value1 :valueN)` -* append: `(:+ :name :value2 :valueN)` -* filter: `(:- :name :value2 :valueN)` -* map: `(:* :name op)` -* reduce: `(:/ :name op)` diff --git a/dsl/proptest-regressions/iter.txt b/dsl/proptest-regressions/iter.txt deleted file mode 100644 index b4d8405..0000000 --- a/dsl/proptest-regressions/iter.txt +++ /dev/null @@ -1,7 +0,0 @@ -# Seeds for failure cases proptest has generated in the past. It is -# automatically read and these particular cases re-run before any -# novel cases are generated. -# -# It is recommended to check this file in to source control so that -# everyone who runs the test benefits from these saved cases. -cc bbb90b16e6106f17dbb5a4f57594f451360a2ea7e3e20c28adeb8babc98d39df # shrinks to source = "(𰀀" diff --git a/dsl/proptest-regressions/token.txt b/dsl/proptest-regressions/token.txt deleted file mode 100644 index cc03cf2..0000000 --- a/dsl/proptest-regressions/token.txt +++ /dev/null @@ -1,7 +0,0 @@ -# Seeds for failure cases proptest has generated in the past. It is -# automatically read and these particular cases re-run before any -# novel cases are generated. -# -# It is recommended to check this file in to source control so that -# everyone who runs the test benefits from these saved cases. -cc 5fb814b74ae035bdecb536817090cfb473f0a874e9acf9aaa136a4794cdb367f # shrinks to source = "", start = 10336420442936153584, length = 8110323630773398032 diff --git a/dsl/src/dsl.rs b/dsl/src/dsl.rs deleted file mode 100644 index ffdf38c..0000000 --- a/dsl/src/dsl.rs +++ /dev/null @@ -1,227 +0,0 @@ -//#![feature(adt_const_params)] -//#![feature(type_alias_impl_trait)] -#![feature(if_let_guard)] -#![feature(impl_trait_in_fn_trait_return)] -#![feature(const_precise_live_drops)] -#![feature(type_alias_impl_trait)] -extern crate const_panic; -use const_panic::PanicFmt; -use std::fmt::Debug; -pub(crate) use ::{ - std::sync::Arc, - //std::error::Error, - konst::iter::for_each, - konst::string::{str_from, str_range, char_indices}, - thiserror::Error, - tengri_core::* -}; -pub(crate) use self::DslError::*; -mod dsl_error; pub use self::dsl_error::*; -mod dsl_ns; pub use self::dsl_ns::*; -mod dsl_word; pub use self::dsl_word::*; -mod dsl_expr; pub use self::dsl_expr::*; -mod dsl_text; pub use self::dsl_text::*; -#[cfg(test)] mod dsl_test; - -// Trait that designates any string-like as potentially parsable DSL. -pub trait Dsl: Debug + Send + Sync { - fn src (&self) -> DslPerhaps<&str> { unreachable!("Dsl::src default impl") } -} -impl<'x> Dsl for &'x str { - fn src (&self) -> DslPerhaps<&str> { Ok(Some(self)) } -} -impl Dsl for Arc { - fn src (&self) -> DslPerhaps<&str> { Ok(Some(self.as_ref())) } -} -impl Dsl for &D { - fn src (&self) -> DslPerhaps<&str> { (*self).src() } -} -impl Dsl for &mut D { - fn src (&self) -> DslPerhaps<&str> { (**self).src() } -} -impl Dsl for Option { - fn src (&self) -> DslPerhaps<&str> {Ok(if let Some(dsl) = self { dsl.src()? } else { None })} -} -impl Dsl for Result { - fn src (&self) -> DslPerhaps<&str> {match self {Ok(dsl) => Ok(dsl.src()?), Err(e) => Err(*e)}} -} - -/// DSL-specific result type. -pub type DslResult = Result; - -/// DSL-specific optional result type. -pub type DslPerhaps = Result, DslError>; - -pub const fn peek (src: &str) -> DslPerhaps<&str> { - Ok(Some(if let Ok(Some(expr)) = expr_peek(src) { expr } else - if let Ok(Some(word)) = word_peek(src) { word } else - if let Ok(Some(text)) = text_peek(src) { text } else - if let Err(e) = no_trailing_non_space(src, 0, Some("peek")) { return Err(e) } - else { return Ok(None) })) -} - -pub const fn seek (src: &str) -> DslPerhaps<(usize, usize)> { - Ok(Some(if let Ok(Some(expr)) = expr_seek(src) { expr } else - if let Ok(Some(word)) = word_seek(src) { word } else - if let Ok(Some(text)) = text_seek(src) { text } else - if let Err(e) = no_trailing_non_space(src, 0, Some("seek")) { return Err(e) } - else { return Ok(None) })) -} - -pub const fn peek_tail (src: &str) -> DslPerhaps<&str> { - match seek(src) { - Err(e) => Err(e), - Ok(None) => Ok(None), - Ok(Some((start, length))) => { - let tail = str_range(src, start + length, src.len()); - for_each!((_i, c) in char_indices(tail) => if !is_space(c) { return Ok(Some(tail)) }); - Ok(None) - }, - } -} - -pub const fn expr_peek_inner (src: &str) -> DslPerhaps<&str> { - match expr_peek(src) { - Ok(Some(peeked)) => { - let len = peeked.len(); - let start = if len > 0 { 1 } else { 0 }; - Ok(Some(str_range(src, start, start + len.saturating_sub(2)))) - }, - e => e - } -} - -pub const fn expr_peek_inner_only (src: &str) -> DslPerhaps<&str> { - match expr_seek(src) { - Err(e) => Err(e), - Ok(None) => Ok(None), - Ok(Some((start, length))) => { - if let Err(e) = no_trailing_non_space(src, start + length, Some("expr_peek_inner_only")) { - Err(e) - } else { - let peeked = str_range(src, start, start + length); - let len = peeked.len(); - let start = if len > 0 { 1 } else { 0 }; - Ok(Some(str_range(peeked, start, start + len.saturating_sub(2)))) - } - }, - } -} - -pub const fn is_space (c: char) -> bool { - matches!(c, ' '|'\n'|'\r'|'\t') -} - -pub const fn no_trailing_non_space ( - src: &str, offset: usize, context: Option<&'static str> -) -> DslResult<()> { - Ok(for_each!((i, c) in char_indices(str_range(src, offset, src.len())) => if !is_space(c) { - return Err(Unexpected(c, Some(offset + i), if let Some(context) = context { - Some(context) - } else { - Some("trailing non-space") - })) - })) -} - -pub const fn is_word_char (c: char) -> bool { - matches!(c, 'a'..='z'|'A'..='Z'|'0'..='9'|'-'|'/'|'@'|':') -} - -pub const fn is_word_end (c: char) -> bool { - is_space(c) || is_expr_end(c) -} - -pub const fn is_text_start (c: char) -> bool { - matches!(c, '"') -} - -pub const fn is_text_end (c: char) -> bool { - matches!(c, '"') -} - -pub const fn is_expr_start (c: char) -> bool { - c == '(' -} - -pub const fn is_expr_end (c: char) -> bool { - c == ')' -} - -pub const fn is_digit (c: char) -> bool { - matches!(c, '0'..='9') -} - -pub const fn to_number (digits: &str) -> Result { - let mut iter = char_indices(digits); - let mut value = 0; - while let Some(((_, c), next)) = iter.next() { - match to_digit(c) { - Ok(digit) => value = 10 * value + digit, - Err(e) => return Err(e), - } - iter = next; - } - Ok(value) -} - -pub const fn to_digit (c: char) -> Result { - Ok(match c { - '0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, - '5' => 5, '6' => 6, '7' => 7, '8' => 8, '9' => 9, - _ => return Err(Unexpected(c, None, Some("parse digit"))) - }) -} - -pub(crate) fn ok_flat (x: Option>) -> DslPerhaps { - Ok(x.transpose()?.flatten()) -} - -#[macro_export] macro_rules! dsl_type (($T:ident { $($trait:tt)* } { - pub const fn $peek:ident $($_1:tt)?; - pub const fn $peek_only:ident $($_2:tt)?; - pub const fn $seek:ident $($_3:tt)?; - pub const fn $seek_start:ident ($source1:ident) $body1:block - pub const fn $seek_length:ident ($source2:ident) $body2:block -})=>{ - pub trait $T: Dsl { $($trait)* } - impl $T for D {} - pub const fn $seek_start ($source1: &str) -> DslPerhaps $body1 - pub const fn $seek_length ($source2: &str) -> DslPerhaps $body2 - /// Find a start and length corresponding to a syntax token. - pub const fn $seek (source: &str) -> DslPerhaps<(usize, usize)> { - match $seek_start(source) { - Err(e) => Err(e), - Ok(None) => Ok(None), - Ok(Some(start)) => match $seek_length(str_from(source, start)) { - Ok(Some(length)) => Ok(Some((start, length))), - Ok(None) => Ok(None), - Err(e) => Err(e), - }, - } - } - /// Find a slice corrensponding to a syntax token. - pub const fn $peek (source: &str) -> DslPerhaps<&str> { - match $seek(source) { - Err(e) => Err(e), - Ok(None) => Ok(None), - Ok(Some((start, length))) => Ok(Some(str_range(source, start, start + length))), - } - } - /// Find a slice corrensponding to a syntax token - /// but return an error if it isn't the only thing - /// in the source. - pub const fn $peek_only (source: &str) -> DslPerhaps<&str> { - match $seek(source) { - Err(e) => Err(e), - Ok(None) => Ok(None), - Ok(Some((start, length))) => { - if let Err(e) = no_trailing_non_space(source, start + length, Some("peek_only")) { - Err(e) - } else { - Ok(Some(str_range(source, start, start + length))) - } - } - } - } -}); diff --git a/dsl/src/dsl_error.rs b/dsl/src/dsl_error.rs deleted file mode 100644 index 11e00c0..0000000 --- a/dsl/src/dsl_error.rs +++ /dev/null @@ -1,25 +0,0 @@ -use crate::*; - -/// DSL-specific error codes. -#[derive(Error, Debug, Copy, Clone, PartialEq, PanicFmt)] -pub enum DslError { - - #[error("parse failed: not implemented")] - Unimplemented, - - #[error("parse failed: empty")] - Empty, - - #[error("parse failed: incomplete")] - Incomplete, - - #[error("parse failed: unexpected character '{0}'")] - Unexpected(char, Option, Option<&'static str>), - - #[error("parse failed: error #{0}")] - Code(u8), - - #[error("end reached")] - End - -} diff --git a/dsl/src/dsl_expr.rs b/dsl/src/dsl_expr.rs deleted file mode 100644 index 92b093e..0000000 --- a/dsl/src/dsl_expr.rs +++ /dev/null @@ -1,87 +0,0 @@ -use crate::*; - -pub type GetDslExpr<'a, S, T> = for<'b> fn(&'a S, &'b str)->Perhaps; - -pub type DslExprs<'a, S, T> = &'a [(&'a str, GetDslExpr<'a, S, T>)]; - -dsl_type!(DslExpr { - fn expr (&self) -> DslPerhaps<&str> {ok_flat(self.src()?.map(expr_peek_inner_only))} - fn head (&self) -> DslPerhaps<&str> {ok_flat(self.src()?.map(peek))} - fn tail (&self) -> DslPerhaps<&str> {ok_flat(self.src()?.map(peek_tail))} - /// my other car is a cdr :< - fn each (&self, mut cb: impl FnMut(&str)->Usually<()>) -> Usually<()> { - Ok(if let Some(head) = self.head()? { - cb(head)?; - if let Some(tail) = self.tail()? { - tail.each(cb)?; - } - }) - } -} { - pub const fn expr_peek [generated]; - pub const fn expr_peek_only [generated]; - pub const fn expr_seek [generated]; - pub const fn expr_seek_start (src) { - for_each!((i, c) in char_indices(src) => - if is_expr_start(c) { return Ok(Some(i)) } else - if !is_space(c) { return Err(Unexpected(c, Some(i), Some("expected expression start"))) }); - Ok(None) - } - pub const fn expr_seek_length (src) { - let mut depth = 0; - for_each!((i, c) in char_indices(src) => - if is_expr_start(c) { depth += 1; } else - if is_expr_end(c) { - if depth == 0 { - return Err(Unexpected(c, Some(i), Some("expected expression end"))) - } else if depth == 1 { - return Ok(Some(i + 1)) - } else { - depth -= 1; - } - }); - Err(Incomplete) - } -}); - -#[macro_export] macro_rules!dsl_exprs(($l:lifetime |$state:ident|->$Type:ty$({ - $($name:literal ($($arg:ident:$ty:ty),* $(,)?) => $body:expr),* $(,)? -})?)=>{ - const EXPRS: DslExprs<$l, Self, $Type> = &[$( $({ - let get: GetDslExpr<$l, Self, $Type> = |$state: &$l Self, tail_base|{ - let tail = tail_base; - $( - let head = tail.head()?.unwrap_or_default(); - let tail = tail.tail()?.unwrap_or_default(); - let $arg: $ty = if let Some(arg) = $state.from(&head)? { - arg - } else { - return Err(format!("{}: arg \"{}\" ({}) got: {head} {tail}", - $name, - stringify!($arg), - stringify!($ty), - ).into()) - }; - )* - Ok(Some($body/* as $Type*/)) - }; - ($name, get) - }),* )? ]; -}); - -pub trait DslNsExprs<'a, T: 'a>: 'a { - /// Known expressions. - const EXPRS: DslExprs<'a, Self, T> = &[]; - /// Resolve an expression if known. - fn from_expr (&'a self, dsl: impl DslExpr + 'a) -> Perhaps { - if let Some(dsl) = dsl.expr()? { - let head = dsl.head()?; - for (key, get) in Self::EXPRS.iter() { - if Some(*key) == head { - return get(self, dsl.tail()?.unwrap_or("")) - } - } - } - Ok(None) - } -} diff --git a/dsl/src/dsl_ns.rs b/dsl/src/dsl_ns.rs deleted file mode 100644 index c8b701f..0000000 --- a/dsl/src/dsl_ns.rs +++ /dev/null @@ -1,46 +0,0 @@ -use crate::*; - -pub trait DslNs<'a, T: 'a>: DslNsWords<'a, T> + DslNsExprs<'a, T> { - /// Resolve an expression or symbol. - fn from (&'a self, dsl: impl Dsl + 'a) -> Perhaps { - if let Ok(Some(literal)) = self.from_literal(&dsl) { - Ok(Some(literal)) - } else if let Ok(Some(meaning)) = self.from_word(&dsl) { - Ok(Some(meaning)) - } else { - self.from_expr(dsl) - } - } - /// Resolve as literal if valid. - fn from_literal (&self, _: impl Dsl) -> Perhaps { - Ok(None) - } -} - -#[macro_export] macro_rules! dsl_ns { - ($State:ty: $Type:ty { - $(literal = |$dsl:ident| $literal:expr;)? - $(word = |$state_w:ident| { - $($word:literal => $body_w:expr),* $(,)? - };)? - $(expr = |$state_e:ident| { - $($head:literal $args:tt => $body_e:expr),* $(,)? - };)? - }) => { - impl<'a> DslNs<'a, $Type> for $State { - $(fn from_literal (&self, $dsl: impl Dsl) -> Perhaps<$Type> { - $literal - })? - } - impl<'a> DslNsWords<'a, $Type> for $State { - $(dsl_words! { 'a |$state_w| -> $Type { - $($word => $body_w),* - } })? - } - impl<'a> DslNsExprs<'a, $Type> for $State { - $(dsl_exprs! { 'a |$state_e| -> $Type { - $($head $args => $body_e),* - } })? - } - } -} diff --git a/dsl/src/dsl_test.rs b/dsl/src/dsl_test.rs deleted file mode 100644 index fb6d6f7..0000000 --- a/dsl/src/dsl_test.rs +++ /dev/null @@ -1,99 +0,0 @@ -use crate::*; -macro_rules!is_some(($expr:expr, $val:expr)=>{assert_eq!($expr, Ok(Some($val)))};); -macro_rules!is_none(($expr:expr)=>{assert_eq!($expr, Ok(None))};); -macro_rules!is_err(($expr:expr)=>{assert!($expr.is_err())}; - ($expr:expr, $err:expr)=>{assert_eq!($expr, Err($err))};); -#[test] fn test_expr () -> Result<(), DslError> { - let e0 = DslError::Unexpected('a', None, None); - let e1 = DslError::Unexpected('(', None, None); - let e2 = DslError::Unexpected('b', None, None); - let e3 = DslError::Unexpected('d', None, None); - let check = |src: &str, word, expr, head, tail|{ - assert_eq!(src.word(), word, "{src}"); - assert_eq!(src.expr(), expr, "{src}"); - assert_eq!(src.head(), head, "{src}"); - assert_eq!(src.tail(), tail, "{src}"); - }; - check("a", Ok(Some("a")), Err(e0), Ok(Some("a")), Ok(None)); - check("(a)", Err(e1), Ok(Some("a")), Ok(Some("(a)")), Ok(None)); - check("a b c", Err(e2), Err(e0), Ok(Some("a")), Ok(Some("b c"))); - check("(a b c)", Err(e1), Ok(Some("a b c")), Ok(Some("(a b c)")), Ok(None)); - check("(a b c) d e f", Err(e1), Err(e3), Ok(Some("(a b c)")), Ok(Some("d e f"))); - check("a (b c d) e f", Err(e1), Err(e0), Ok(Some("a")), Ok(Some("(b c d) e f"))); - - is_some!(word_peek("\n :view/transport"), ":view/transport"); - - assert!(is_space(' ')); - assert!(!is_word_char(' ')); - assert!(is_word_char('f')); - - is_some!(word_seek_start("foo"), 0); - is_some!(word_seek_start("foo "), 0); - is_some!(word_seek_start(" foo "), 1); - is_some!(word_seek_length(&" foo "[1..]), 3); - is_some!(word_seek("foo"), (0, 3)); - is_some!(word_peek("foo"), "foo"); - is_some!(word_seek("foo "), (0, 3)); - is_some!(word_peek("foo "), "foo"); - is_some!(word_seek(" foo "), (1, 3)); - is_some!(word_peek(" foo "), "foo"); - - is_err!("(foo)".word()); - is_err!("foo".expr()); - - is_some!("(foo)".expr(), "foo"); - is_some!("(foo)".head(), "(foo)"); - is_none!("(foo)".tail()); - - is_some!("(foo bar baz)".expr(), "foo bar baz"); - is_some!("(foo bar baz)".head(), "(foo bar baz)"); - is_none!("(foo bar baz)".tail()); - - is_some!("(foo bar baz)".expr().head(), "foo"); - is_some!("(foo bar baz)".expr().tail(), "bar baz"); - is_some!("(foo bar baz)".expr().tail().head(), "bar"); - is_some!("(foo bar baz)".expr().tail().tail(), "baz"); - - is_err!("foo".expr()); - is_some!("foo".word(), "foo"); - is_some!(" foo".word(), "foo"); - is_some!(" foo ".word(), "foo"); - - is_some!(" foo ".head(), "foo"); - //assert_eq!(" foo ".head().head(), Ok(None)); - is_none!(" foo ".head().tail()); - is_none!(" foo ".tail()); - is_none!(" foo ".tail().head()); - is_none!(" foo ".tail().tail()); - - assert_eq!(" foo bar ".head(), Ok(Some("foo"))); - //assert_eq!(" foo bar ".head().head(), Ok(None)); - assert_eq!(" foo bar ".head().tail(), Ok(None)); - assert_eq!(" foo bar ".tail(), Ok(Some(" bar "))); - assert_eq!(" foo bar ".tail().head(), Ok(Some("bar"))); - assert_eq!(" foo bar ".tail().tail(), Ok(None)); - - assert_eq!(" (foo) ".head(), Ok(Some("(foo)"))); - //assert_eq!(" (foo) ".head().head(), Ok(Some("foo"))); - //assert_eq!(" (foo) ".head().head().head(), Ok(None)); - assert_eq!(" (foo) ".tail(), Ok(None)); - - assert_eq!(" (foo) (bar) ".head(), Ok(Some("(foo)"))); - //assert_eq!(" (foo) (bar) ".head().head(), Ok(Some("foo"))); - //assert_eq!(" (foo) (bar) ".head().head().head(), Ok(None)); - is_some!(" (foo) (bar) ".tail(), " (bar) "); - is_some!(" (foo) (bar) ".tail().head(), "(bar)"); - is_some!(" (foo) (bar) ".tail().head().head(), "(bar)"); - is_some!(" (foo) (bar) ".tail().head().expr(), "bar"); - is_some!(" (foo) (bar) ".tail().head().expr().head(), "bar"); - - is_some!(" (foo bar baz) ".head(), "(foo bar baz)"); - is_some!(" (foo bar baz) ".head().head(), "(foo bar baz)"); - is_some!(" (foo bar baz) ".expr(), "foo bar baz"); - is_some!(" (foo bar baz) ".expr().head(), "foo"); - is_some!(" (foo bar baz) ".expr().tail(), "bar baz"); - is_some!(" (foo bar baz) ".expr().tail().head(), "bar"); - is_some!(" (foo bar baz) ".expr().tail().tail(), "baz"); - is_none!(" (foo bar baz) ".tail()); - Ok(()) -} diff --git a/dsl/src/dsl_text.rs b/dsl/src/dsl_text.rs deleted file mode 100644 index 9c2e51d..0000000 --- a/dsl/src/dsl_text.rs +++ /dev/null @@ -1,20 +0,0 @@ -use crate::*; - -dsl_type!(DslText { - fn text (&self) -> DslPerhaps<&str> { ok_flat(self.src()?.map(text_peek_only)) } -} { - pub const fn text_peek [generated]; - pub const fn text_peek_only [generated]; - pub const fn text_seek [generated]; - pub const fn text_seek_start (src) { - for_each!((i, c) in char_indices(src) => - if is_text_start(c) { return Ok(Some(i)) } else - if !is_space(c) { return Err(Unexpected(c, Some(i), None)) }); - Ok(None) - } - pub const fn text_seek_length (src) { - for_each!((i, c) in char_indices(src) => - if is_text_end(c) { return Ok(Some(i)) }); - Ok(None) - } -}); diff --git a/dsl/src/dsl_word.rs b/dsl/src/dsl_word.rs deleted file mode 100644 index 5abb61a..0000000 --- a/dsl/src/dsl_word.rs +++ /dev/null @@ -1,49 +0,0 @@ -use crate::*; - -pub type GetDslWord<'a, S, T> = fn(&'a S)->Perhaps; - -pub type DslWords<'a, S, T> = &'a [(&'a str, GetDslWord<'a, S, T>)]; - -dsl_type!(DslWord { - fn word (&self) -> DslPerhaps<&str> {ok_flat(self.src()?.map(word_peek_only))} -} { - pub const fn word_peek [generated]; - pub const fn word_peek_only [generated]; - pub const fn word_seek [generated]; - pub const fn word_seek_start (src) { - for_each!((i, c) in char_indices(src) => if - is_word_char(c) { return Ok(Some(i)) } else - if !is_space(c) { return Err(Unexpected(c, Some(i), Some("word_seek_start"))) }); - Ok(None) - } - pub const fn word_seek_length (src) { - for_each!((i, c) in char_indices(src) => if !is_word_char(c) { return Ok(Some(i)) }); - Ok(Some(src.len())) - } -}); - -#[macro_export] macro_rules!dsl_words(($l:lifetime |$state:ident|->$Type:ty$({ - $($word:literal => $body:expr),* $(,)? -})?)=>{ - const WORDS: DslWords<$l, Self, $Type> = &[$( $({ - let get: GetDslWord<$l, Self, $Type> = |$state: &$l Self|Ok(Some($body)); - ($word, get) - }),* )?]; -}); - -pub trait DslNsWords<'a, T: 'a>: 'a { - /// Known symbols. - const WORDS: DslWords<'a, Self, T> = &[]; - /// Resolve a symbol if known. - fn from_word (&'a self, dsl: impl DslWord) -> Perhaps { - if let Some(dsl) = dsl.word()? { - for (key, get) in Self::WORDS.iter() { - if dsl == *key { - let value = get(self); - return value - } - } - } - return Ok(None) - } -} diff --git a/dsl/test.edn b/dsl/test.edn deleted file mode 100644 index 7e79d1a..0000000 --- a/dsl/test.edn +++ /dev/null @@ -1 +0,0 @@ -(bsp/n (fixed/y 2 :transport) (bsp/s (fixed/y 2 :status) (fill/xy (bsp/a (fill/xy (align/e :pool)) :arranger)))) diff --git a/editor/Cargo.toml b/editor/Cargo.toml deleted file mode 100644 index 692cf03..0000000 --- a/editor/Cargo.toml +++ /dev/null @@ -1,5 +0,0 @@ -[package] -name = "tengri_editor" -description = "Embeddable editor for Tengri DSL." -version = { workspace = true } -edition = { workspace = true } diff --git a/editor/src/main.rs b/editor/src/main.rs deleted file mode 100644 index e69de29..0000000 diff --git a/input/Cargo.toml b/input/Cargo.toml index 0c9218d..506c636 100644 --- a/input/Cargo.toml +++ b/input/Cargo.toml @@ -8,8 +8,7 @@ edition = { workspace = true } path = "input.rs" [dependencies] -tengri_core = { path = "../core" } +dizzle = { path = "../../dizzle" } [dev-dependencies] tengri_tui = { path = "../tui" } -tengri_dsl = { path = "../dsl" } diff --git a/input/input.rs b/input/input.rs index 5a22800..b251232 100644 --- a/input/input.rs +++ b/input/input.rs @@ -1,7 +1,7 @@ #![feature(associated_type_defaults)] #![feature(if_let_guard)] -pub(crate) use tengri_core::*; +pub(crate) use dizzle::*; #[cfg(test)] mod input_test; diff --git a/output/Cargo.toml b/output/Cargo.toml index ed7f210..ac61804 100644 --- a/output/Cargo.toml +++ b/output/Cargo.toml @@ -4,21 +4,16 @@ description = "UI metaframework, output layer." version = { workspace = true } edition = { workspace = true } -[lib] -path = "src/output.rs" - [features] bumpalo = [ "dep:bumpalo" ] -dsl = [ "dep:tengri_dsl" ] +dsl = [] [dependencies] -tengri_core = { path = "../core" } -tengri_dsl = { optional = true, path = "../dsl" } -bumpalo = { optional = true, workspace = true } +dizzle = { path = "../../dizzle" } +bumpalo = { optional = true, workspace = true } [dev-dependencies] tengri = { path = "../tengri", features = [ "dsl", "tui" ] } tengri_tui = { path = "../tui" } -tengri_dsl = { path = "../dsl" } proptest = { workspace = true } proptest-derive = { workspace = true } diff --git a/output/src/lib.rs b/output/src/lib.rs new file mode 100644 index 0000000..17e62f7 --- /dev/null +++ b/output/src/lib.rs @@ -0,0 +1,200 @@ +#![feature(step_trait)] +#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] +#![feature(const_precise_live_drops)] +#![feature(type_changing_struct_update)] +#![feature(anonymous_lifetime_in_impl_trait)] +#![feature(const_option_ops)] +#![feature(const_trait_impl)] +#![feature(const_default)] +#![feature(trait_alias)] +//#![feature(non_lifetime_binders)] +pub(crate) use self::Direction::*; +pub(crate) use std::fmt::{Debug, Display}; +pub(crate) use std::marker::PhantomData; +pub(crate) use std::ops::{Add, Sub, Mul, Div}; +pub(crate) use std::sync::{Arc, RwLock, atomic::{AtomicUsize, Ordering::Relaxed}}; +pub(crate) use dizzle::*; +mod output; pub use self::output::*; +mod content; pub use self::content::*; +mod draw; pub use self::draw::*; +mod group; pub use self::group::*; +mod layout; pub use self::layout::*; +mod space; pub use self::space::*; +mod thunk; pub use self::thunk::*; +mod widget; pub use self::widget::*; +#[cfg(feature = "dsl")] mod view; +#[cfg(feature = "dsl")] pub use self::view::*; +#[cfg(test)] pub(crate) use proptest_derive::Arbitrary; +#[cfg(test)] mod test { + use crate::{*, Direction::*}; + //use proptest_derive::Arbitrary; + use proptest::{prelude::*, option::of}; + + proptest! { + #[test] fn proptest_direction ( + d in prop_oneof![ + Just(North), Just(South), + Just(East), Just(West), + Just(Above), Just(Below) + ], + x in u16::MIN..u16::MAX, + y in u16::MIN..u16::MAX, + w in u16::MIN..u16::MAX, + h in u16::MIN..u16::MAX, + a in u16::MIN..u16::MAX, + ) { + let _ = d.split_fixed([x, y, w, h], a); + } + } + + proptest! { + #[test] fn proptest_size ( + x in u16::MIN..u16::MAX, + y in u16::MIN..u16::MAX, + a in u16::MIN..u16::MAX, + b in u16::MIN..u16::MAX, + ) { + let size = [x, y]; + let _ = size.w(); + let _ = size.h(); + let _ = size.wh(); + let _ = size.clip_w(a); + let _ = size.clip_h(b); + let _ = size.expect_min(a, b); + let _ = size.to_area_pos(); + let _ = size.to_area_size(); + } + } + + proptest! { + #[test] fn proptest_area ( + x in u16::MIN..u16::MAX, + y in u16::MIN..u16::MAX, + w in u16::MIN..u16::MAX, + h in u16::MIN..u16::MAX, + a in u16::MIN..u16::MAX, + b in u16::MIN..u16::MAX, + ) { + let _: [u16;4] = <[u16;4] as Area>::zero(); + let _: [u16;4] = <[u16;4] as Area>::from_position([a, b]); + let _: [u16;4] = <[u16;4] as Area>::from_size([a, b]); + let area: [u16;4] = [x, y, w, h]; + let _ = area.expect_min(a, b); + let _ = area.xy(); + let _ = area.wh(); + let _ = area.xywh(); + let _ = area.clip_h(a); + let _ = area.clip_w(b); + let _ = area.clip([a, b]); + let _ = area.set_w(a); + let _ = area.set_h(b); + let _ = area.x2(); + let _ = area.y2(); + let _ = area.lrtb(); + let _ = area.center(); + let _ = area.center_x(a); + let _ = area.center_y(b); + let _ = area.center_xy([a, b]); + let _ = area.centered(); + } + } + + macro_rules! test_op_transform { + ($fn:ident, $Op:ident) => { + proptest! { + #[test] fn $fn ( + op_x in of(u16::MIN..u16::MAX), + op_y in of(u16::MIN..u16::MAX), + content in "\\PC*", + x in u16::MIN..u16::MAX, + y in u16::MIN..u16::MAX, + w in u16::MIN..u16::MAX, + h in u16::MIN..u16::MAX, + ) { + if let Some(op) = match (op_x, op_y) { + (Some(x), Some(y)) => Some($Op::XY(x, y, content)), + (Some(x), None) => Some($Op::X(x, content)), + (None, Some(y)) => Some($Op::y(y, content)), + _ => None + } { + //assert_eq!(Content::layout(&op, [x, y, w, h]), + //Draw::layout(&op, [x, y, w, h])); + } + } + } + } + } + + test_op_transform!(proptest_op_fixed, Fixed); + test_op_transform!(proptest_op_min, Min); + test_op_transform!(proptest_op_max, Max); + test_op_transform!(proptest_op_push, Push); + test_op_transform!(proptest_op_pull, Pull); + test_op_transform!(proptest_op_shrink, Shrink); + test_op_transform!(proptest_op_expand, Expand); + test_op_transform!(proptest_op_padding, Pad); + + proptest! { + #[test] fn proptest_op_bsp ( + d in prop_oneof![ + Just(North), Just(South), + Just(East), Just(West), + Just(Above), Just(Below) + ], + a in "\\PC*", + b in "\\PC*", + x in u16::MIN..u16::MAX, + y in u16::MIN..u16::MAX, + w in u16::MIN..u16::MAX, + h in u16::MIN..u16::MAX, + ) { + let bsp = Bsp(d, a, b); + //assert_eq!( + //Content::layout(&bsp, [x, y, w, h]), + //Draw::layout(&bsp, [x, y, w, h]), + //); + } + } + + #[test] fn test_stub_output () -> Usually<()> { + use crate::*; + struct TestOut([u16;4]); + impl Out for TestOut { + type Unit = u16; + type Size = [u16;2]; + type Area = [u16;4]; + fn area (&self) -> [u16;4] { + self.0 + } + fn area_mut (&mut self) -> &mut [u16;4] { + &mut self.0 + } + fn place_at + ?Sized> (&mut self, area: [u16;4], _: &T) { + println!("place_at: {area:?}"); + () + } + } + impl Draw for String { + fn draw (&self, to: &mut TestOut) { + to.area_mut().set_w(self.len() as u16); + } + } + Ok(()) + } + + #[test] fn test_space () { + use crate::*; + assert_eq!(Area::center(&[10u16, 10, 20, 20]), [20, 20]); + } + + #[test] fn test_iter_map () { + struct Foo; + impl Content for Foo {} + fn _make_map + Send + Sync> (data: &Vec) -> impl Draw { + Map::new(||data.iter(), |_foo, _index|{}) + } + let _data = vec![Foo, Foo, Foo]; + //let map = make_map(&data); + } +} diff --git a/output/src/output.rs b/output/src/output.rs index 5da748f..7f0294e 100644 --- a/output/src/output.rs +++ b/output/src/output.rs @@ -1,21 +1,4 @@ -#![feature(step_trait)] -#![feature(type_alias_impl_trait)] -#![feature(impl_trait_in_assoc_type)] -#![feature(const_precise_live_drops)] -#![feature(type_changing_struct_update)] -#![feature(anonymous_lifetime_in_impl_trait)] -#![feature(const_option_ops)] -#![feature(const_trait_impl)] -#![feature(const_default)] -#![feature(trait_alias)] -//#![feature(non_lifetime_binders)] - -pub(crate) use self::Direction::*; -pub(crate) use std::fmt::{Debug, Display}; -pub(crate) use std::marker::PhantomData; -pub(crate) use std::ops::{Add, Sub, Mul, Div}; -pub(crate) use std::sync::{Arc, RwLock, atomic::{AtomicUsize, Ordering::Relaxed}}; -pub(crate) use tengri_core::*; +use crate::*; /// Drawing target. pub trait Out: Send + Sync + Sized { @@ -49,17 +32,3 @@ pub trait Out: Send + Sync + Sized { /// Mutable pointer to area. fn area_mut (&mut self) -> &mut Self::Area; } - -#[cfg(test)] mod output_test; -#[cfg(test)] pub(crate) use proptest_derive::Arbitrary; - -mod content; pub use self::content::*; -mod draw; pub use self::draw::*; -mod group; pub use self::group::*; -mod layout; pub use self::layout::*; -mod space; pub use self::space::*; -mod thunk; pub use self::thunk::*; -mod widget; pub use self::widget::*; - -#[cfg(feature = "dsl")] mod view; -#[cfg(feature = "dsl")] pub use self::view::*; diff --git a/output/src/output_test.rs b/output/src/output_test.rs deleted file mode 100644 index 932e87a..0000000 --- a/output/src/output_test.rs +++ /dev/null @@ -1,170 +0,0 @@ -use crate::{*, Direction::*}; -//use proptest_derive::Arbitrary; -use proptest::{prelude::*, option::of}; - -proptest! { - #[test] fn proptest_direction ( - d in prop_oneof![ - Just(North), Just(South), - Just(East), Just(West), - Just(Above), Just(Below) - ], - x in u16::MIN..u16::MAX, - y in u16::MIN..u16::MAX, - w in u16::MIN..u16::MAX, - h in u16::MIN..u16::MAX, - a in u16::MIN..u16::MAX, - ) { - let _ = d.split_fixed([x, y, w, h], a); - } -} - -proptest! { - #[test] fn proptest_size ( - x in u16::MIN..u16::MAX, - y in u16::MIN..u16::MAX, - a in u16::MIN..u16::MAX, - b in u16::MIN..u16::MAX, - ) { - let size = [x, y]; - let _ = size.w(); - let _ = size.h(); - let _ = size.wh(); - let _ = size.clip_w(a); - let _ = size.clip_h(b); - let _ = size.expect_min(a, b); - let _ = size.to_area_pos(); - let _ = size.to_area_size(); - } -} - -proptest! { - #[test] fn proptest_area ( - x in u16::MIN..u16::MAX, - y in u16::MIN..u16::MAX, - w in u16::MIN..u16::MAX, - h in u16::MIN..u16::MAX, - a in u16::MIN..u16::MAX, - b in u16::MIN..u16::MAX, - ) { - let _: [u16;4] = <[u16;4] as Area>::zero(); - let _: [u16;4] = <[u16;4] as Area>::from_position([a, b]); - let _: [u16;4] = <[u16;4] as Area>::from_size([a, b]); - let area: [u16;4] = [x, y, w, h]; - let _ = area.expect_min(a, b); - let _ = area.xy(); - let _ = area.wh(); - let _ = area.xywh(); - let _ = area.clip_h(a); - let _ = area.clip_w(b); - let _ = area.clip([a, b]); - let _ = area.set_w(a); - let _ = area.set_h(b); - let _ = area.x2(); - let _ = area.y2(); - let _ = area.lrtb(); - let _ = area.center(); - let _ = area.center_x(a); - let _ = area.center_y(b); - let _ = area.center_xy([a, b]); - let _ = area.centered(); - } -} - -macro_rules! test_op_transform { - ($fn:ident, $Op:ident) => { - proptest! { - #[test] fn $fn ( - op_x in of(u16::MIN..u16::MAX), - op_y in of(u16::MIN..u16::MAX), - content in "\\PC*", - x in u16::MIN..u16::MAX, - y in u16::MIN..u16::MAX, - w in u16::MIN..u16::MAX, - h in u16::MIN..u16::MAX, - ) { - if let Some(op) = match (op_x, op_y) { - (Some(x), Some(y)) => Some($Op::XY(x, y, content)), - (Some(x), None) => Some($Op::X(x, content)), - (None, Some(y)) => Some($Op::y(y, content)), - _ => None - } { - //assert_eq!(Content::layout(&op, [x, y, w, h]), - //Draw::layout(&op, [x, y, w, h])); - } - } - } - } -} - -test_op_transform!(proptest_op_fixed, Fixed); -test_op_transform!(proptest_op_min, Min); -test_op_transform!(proptest_op_max, Max); -test_op_transform!(proptest_op_push, Push); -test_op_transform!(proptest_op_pull, Pull); -test_op_transform!(proptest_op_shrink, Shrink); -test_op_transform!(proptest_op_expand, Expand); -test_op_transform!(proptest_op_padding, Pad); - -proptest! { - #[test] fn proptest_op_bsp ( - d in prop_oneof![ - Just(North), Just(South), - Just(East), Just(West), - Just(Above), Just(Below) - ], - a in "\\PC*", - b in "\\PC*", - x in u16::MIN..u16::MAX, - y in u16::MIN..u16::MAX, - w in u16::MIN..u16::MAX, - h in u16::MIN..u16::MAX, - ) { - let bsp = Bsp(d, a, b); - //assert_eq!( - //Content::layout(&bsp, [x, y, w, h]), - //Draw::layout(&bsp, [x, y, w, h]), - //); - } -} - -#[test] fn test_stub_output () -> Usually<()> { - use crate::*; - struct TestOut([u16;4]); - impl Out for TestOut { - type Unit = u16; - type Size = [u16;2]; - type Area = [u16;4]; - fn area (&self) -> [u16;4] { - self.0 - } - fn area_mut (&mut self) -> &mut [u16;4] { - &mut self.0 - } - fn place_at + ?Sized> (&mut self, area: [u16;4], _: &T) { - println!("place_at: {area:?}"); - () - } - } - impl Draw for String { - fn draw (&self, to: &mut TestOut) { - to.area_mut().set_w(self.len() as u16); - } - } - Ok(()) -} - -#[test] fn test_space () { - use crate::*; - assert_eq!(Area::center(&[10u16, 10, 20, 20]), [20, 20]); -} - -#[test] fn test_iter_map () { - struct Foo; - impl Content for Foo {} - fn _make_map + Send + Sync> (data: &Vec) -> impl Draw { - Map::new(||data.iter(), |_foo, _index|{}) - } - let _data = vec![Foo, Foo, Foo]; - //let map = make_map(&data); -} diff --git a/output/src/view.rs b/output/src/view.rs index f8a182f..8e62c91 100644 --- a/output/src/view.rs +++ b/output/src/view.rs @@ -1,5 +1,5 @@ use crate::*; -use ::tengri_dsl::{Dsl, DslExpr, DslWord, DslNs}; +use ::dizzle::{Dsl, DslExpr, DslWord, DslNs}; pub trait View { fn view_expr <'a> (&'a self, output: &mut O, expr: &'a impl DslExpr) -> Usually { diff --git a/proc/Cargo.toml b/proc/Cargo.toml index 19fe50c..839b1c6 100644 --- a/proc/Cargo.toml +++ b/proc/Cargo.toml @@ -8,7 +8,7 @@ edition = { workspace = true } proc-macro = true [dependencies] -tengri_core = { path = "../core" } +dizzle = { path = "../../dizzle" } syn = { workspace = true } quote = { workspace = true } proc-macro2 = { workspace = true } diff --git a/tengri/Cargo.toml b/tengri/Cargo.toml index 74b46ad..e67c76e 100644 --- a/tengri/Cargo.toml +++ b/tengri/Cargo.toml @@ -9,18 +9,17 @@ default = [ "input", "output", "tui" ] input = [ "tengri_input" ] output = [ "tengri_output" ] tui = [ "tengri_tui" ] -dsl = [ "tengri_dsl", "tengri_output/dsl", "tengri_tui/dsl" ] +dsl = [ "tengri_output/dsl", "tengri_tui/dsl" ] [dependencies] -tengri_core = { workspace = true } -tengri_dsl = { optional = true, path = "../dsl" } -tengri_input = { optional = true, path = "../input" } -tengri_output = { optional = true, path = "../output" } -tengri_tui = { optional = true, path = "../tui" } +dizzle = { workspace = true } +tengri_input = { workspace = true, optional = true } +tengri_output = { workspace = true, optional = true } +tengri_tui = { workspace = true, optional = true } [dev-dependencies] -tengri_proc = { path = "../proc" } -tengri = { path = ".", features = [ "dsl" ] } +tengri_proc = { workspace = true } +tengri = { workspace = true, features = [ "dsl" ] } crossterm = { workspace = true } [target.'cfg(target_os = "linux")'] diff --git a/tengri/src/lib.rs b/tengri/src/lib.rs index 972a702..5b12960 100644 --- a/tengri/src/lib.rs +++ b/tengri/src/lib.rs @@ -1,8 +1,112 @@ -pub use ::tengri_core::*; +pub use ::dizzle::*; #[cfg(feature="output")] pub use ::tengri_output as output; #[cfg(feature="input")] pub use ::tengri_input as input; -#[cfg(feature="dsl")] pub use ::tengri_dsl as dsl; #[cfg(feature="tui")] pub use ::tengri_tui as tui; #[cfg(test)] extern crate tengri_proc; -#[cfg(test)] mod test; +#[cfg(test)] mod test { + // FIXME + //use crate::*; + //use crate::{dsl::*, input::*, tui::TuiIn}; + //use crossterm::event::{Event, KeyEvent, KeyCode, KeyModifiers, KeyEventKind, KeyEventState}; + //use std::cmp::Ordering; + + //#[test] fn test_subcommand () -> Usually<()> { + //#[derive(Debug)] struct Event(crossterm::event::Event); + //impl Eq for Event {} + //impl PartialEq for Event { fn eq (&self, other: &Self) -> bool { todo!() } } + //impl Ord for Event { fn cmp (&self, other: &Self) -> Ordering { todo!() } } + //impl PartialOrd for Event { fn partial_cmp (&self, other: &Self) -> Option { None } } + //struct Test { keys: InputMap } + + //handle!(TuiIn: |self: Test, input|Ok(None));[>if let Some(command) = self.keys.command(self, input) { + //Ok(Some(true)) + //} else { + //Ok(None) + //});*/ + + //#[tengri_proc::command(Test)] + //impl TestCommand { + //fn do_thing (_state: &mut Test) -> Perhaps { + //Ok(None) + //} + //fn do_thing_arg (_state: &mut Test, _arg: usize) -> Perhaps { + //Ok(None) + //} + //fn do_sub (state: &mut Test, command: TestSubcommand) -> Perhaps { + //Ok(command.execute(state)?.map(|command|Self::DoSub { command })) + //} + //} + + //#[tengri_proc::command(Test)] + //impl TestSubcommand { + //fn do_other_thing (_state: &mut Test) -> Perhaps { + //Ok(None) + //} + //fn do_other_thing_arg (_state: &mut Test, _arg: usize) -> Perhaps { + //Ok(None) + //} + //} + + //let mut test = Test { + //keys: InputMap::from_source(" + //(@a do-thing) + //(@b do-thing-arg 0) + //(@c do-sub do-other-thing) + //(@d do-sub do-other-thing-arg 0) + //")? + //}; + + ////assert_eq!(Some(true), test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent { + ////kind: KeyEventKind::Press, + ////code: KeyCode::Char('a'), + ////modifiers: KeyModifiers::NONE, + ////state: KeyEventState::NONE, + ////})))?); + ////assert_eq!(Some(true), test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent { + ////kind: KeyEventKind::Press, + ////code: KeyCode::Char('b'), + ////modifiers: KeyModifiers::NONE, + ////state: KeyEventState::NONE, + ////})))?); + ////assert_eq!(Some(true), test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent { + ////kind: KeyEventKind::Press, + ////code: KeyCode::Char('c'), + ////modifiers: KeyModifiers::NONE, + ////state: KeyEventState::NONE, + ////})))?); + ////assert_eq!(Some(true), test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent { + ////kind: KeyEventKind::Press, + ////code: KeyCode::Char('d'), + ////modifiers: KeyModifiers::NONE, + ////state: KeyEventState::NONE, + ////})))?); + ////assert_eq!(None, test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent { + ////kind: KeyEventKind::Press, + ////code: KeyCode::Char('z'), + ////modifiers: KeyModifiers::NONE, + ////state: KeyEventState::NONE, + ////})))?); + //Ok(()) + //} + + //FIXME: + //#[cfg(test)] #[test] fn test_dsl_context () { + //use crate::dsl::{Dsl, Value}; + + //struct Test; + //#[tengri_proc::expose] + //impl Test { + //fn some_bool (&self) -> bool { + //true + //} + //} + //assert_eq!(Dsl::get(&Test, &Value::Sym(":false")), Some(false)); + //assert_eq!(Dsl::get(&Test, &Value::Sym(":true")), Some(true)); + //assert_eq!(Dsl::get(&Test, &Value::Sym(":some-bool")), Some(true)); + //assert_eq!(Dsl::get(&Test, &Value::Sym(":missing-bool")), None); + //assert_eq!(Dsl::get(&Test, &Value::Num(0)), Some(false)); + //assert_eq!(Dsl::get(&Test, &Value::Num(1)), Some(true)); + //} + +} diff --git a/tengri/src/test.rs b/tengri/src/test.rs deleted file mode 100644 index 2df3c8a..0000000 --- a/tengri/src/test.rs +++ /dev/null @@ -1,103 +0,0 @@ -// FIXME -//use crate::*; -//use crate::{dsl::*, input::*, tui::TuiIn}; -//use crossterm::event::{Event, KeyEvent, KeyCode, KeyModifiers, KeyEventKind, KeyEventState}; -//use std::cmp::Ordering; - -//#[test] fn test_subcommand () -> Usually<()> { - //#[derive(Debug)] struct Event(crossterm::event::Event); - //impl Eq for Event {} - //impl PartialEq for Event { fn eq (&self, other: &Self) -> bool { todo!() } } - //impl Ord for Event { fn cmp (&self, other: &Self) -> Ordering { todo!() } } - //impl PartialOrd for Event { fn partial_cmp (&self, other: &Self) -> Option { None } } - //struct Test { keys: InputMap } - - //handle!(TuiIn: |self: Test, input|Ok(None));[>if let Some(command) = self.keys.command(self, input) { - //Ok(Some(true)) - //} else { - //Ok(None) - //});*/ - - //#[tengri_proc::command(Test)] - //impl TestCommand { - //fn do_thing (_state: &mut Test) -> Perhaps { - //Ok(None) - //} - //fn do_thing_arg (_state: &mut Test, _arg: usize) -> Perhaps { - //Ok(None) - //} - //fn do_sub (state: &mut Test, command: TestSubcommand) -> Perhaps { - //Ok(command.execute(state)?.map(|command|Self::DoSub { command })) - //} - //} - - //#[tengri_proc::command(Test)] - //impl TestSubcommand { - //fn do_other_thing (_state: &mut Test) -> Perhaps { - //Ok(None) - //} - //fn do_other_thing_arg (_state: &mut Test, _arg: usize) -> Perhaps { - //Ok(None) - //} - //} - - //let mut test = Test { - //keys: InputMap::from_source(" - //(@a do-thing) - //(@b do-thing-arg 0) - //(@c do-sub do-other-thing) - //(@d do-sub do-other-thing-arg 0) - //")? - //}; - - ////assert_eq!(Some(true), test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent { - ////kind: KeyEventKind::Press, - ////code: KeyCode::Char('a'), - ////modifiers: KeyModifiers::NONE, - ////state: KeyEventState::NONE, - ////})))?); - ////assert_eq!(Some(true), test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent { - ////kind: KeyEventKind::Press, - ////code: KeyCode::Char('b'), - ////modifiers: KeyModifiers::NONE, - ////state: KeyEventState::NONE, - ////})))?); - ////assert_eq!(Some(true), test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent { - ////kind: KeyEventKind::Press, - ////code: KeyCode::Char('c'), - ////modifiers: KeyModifiers::NONE, - ////state: KeyEventState::NONE, - ////})))?); - ////assert_eq!(Some(true), test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent { - ////kind: KeyEventKind::Press, - ////code: KeyCode::Char('d'), - ////modifiers: KeyModifiers::NONE, - ////state: KeyEventState::NONE, - ////})))?); - ////assert_eq!(None, test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent { - ////kind: KeyEventKind::Press, - ////code: KeyCode::Char('z'), - ////modifiers: KeyModifiers::NONE, - ////state: KeyEventState::NONE, - ////})))?); - //Ok(()) -//} - -//FIXME: -//#[cfg(test)] #[test] fn test_dsl_context () { - //use crate::dsl::{Dsl, Value}; - - //struct Test; - //#[tengri_proc::expose] - //impl Test { - //fn some_bool (&self) -> bool { - //true - //} - //} - //assert_eq!(Dsl::get(&Test, &Value::Sym(":false")), Some(false)); - //assert_eq!(Dsl::get(&Test, &Value::Sym(":true")), Some(true)); - //assert_eq!(Dsl::get(&Test, &Value::Sym(":some-bool")), Some(true)); - //assert_eq!(Dsl::get(&Test, &Value::Sym(":missing-bool")), None); - //assert_eq!(Dsl::get(&Test, &Value::Num(0)), Some(false)); - //assert_eq!(Dsl::get(&Test, &Value::Num(1)), Some(true)); -//} diff --git a/tui/Cargo.toml b/tui/Cargo.toml index 3e9ab61..236e778 100644 --- a/tui/Cargo.toml +++ b/tui/Cargo.toml @@ -4,24 +4,20 @@ description = "UI metaframework, Ratatui backend." version = { workspace = true } edition = { workspace = true } -[lib] -path = "src/tui.rs" - [features] -dsl = [ "dep:tengri_dsl", "tengri_output/dsl" ] +dsl = [ "tengri_output/dsl" ] bumpalo = [ "dep:bumpalo" ] [dependencies] -tengri_core = { workspace = true } +dizzle = { workspace = true } + tengri_input = { workspace = true } tengri_output = { workspace = true } -tengri_dsl = { workspace = true, optional = true } atomic_float = { workspace = true } better-panic = { workspace = true } bumpalo = { workspace = true, optional = true } crossterm = { workspace = true } -konst = { workspace = true } palette = { workspace = true } quanta = { workspace = true } rand = { workspace = true } @@ -30,5 +26,4 @@ unicode-width = { workspace = true } [dev-dependencies] tengri = { workspace = true, features = [ "dsl" ] } -tengri_dsl = { workspace = true } tengri_proc = { workspace = true } diff --git a/tui/src/lib.rs b/tui/src/lib.rs new file mode 100644 index 0000000..081928c --- /dev/null +++ b/tui/src/lib.rs @@ -0,0 +1,29 @@ +#![feature(type_changing_struct_update)] +#![feature(trait_alias)] +#[cfg(test)] mod tui_test; +mod tui_engine; pub use self::tui_engine::*; +mod tui_content; pub use self::tui_content::*; +pub use ::{tengri_input, tengri_output, ratatui, crossterm, palette, better_panic}; +pub(crate) use ::{ + dizzle::*, + tengri_input::*, + tengri_output::*, + atomic_float::AtomicF64, + std::{io::{stdout, Stdout}, sync::{Arc, RwLock, atomic::{AtomicBool, Ordering::*}}}, + better_panic::{Settings, Verbosity}, + palette::{*, convert::*, okhsl::*}, + ratatui::{ + prelude::{Color, Style, Buffer}, + style::Modifier, + backend::{Backend, CrosstermBackend, ClearType}, + layout::{Size, Rect}, + buffer::Cell + }, + crossterm::{ + ExecutableCommand, + terminal::{EnterAlternateScreen, LeaveAlternateScreen, enable_raw_mode, disable_raw_mode}, + event::{Event, KeyEvent, KeyCode, KeyModifiers, KeyEventKind, KeyEventState}, + } +}; + + diff --git a/tui/src/tui.rs b/tui/src/tui.rs index 853d99d..d017dff 100644 --- a/tui/src/tui.rs +++ b/tui/src/tui.rs @@ -1,39 +1,5 @@ -#![feature(type_changing_struct_update)] -#![feature(trait_alias)] -#[cfg(test)] mod tui_test; -mod tui_engine; pub use self::tui_engine::*; -mod tui_content; pub use self::tui_content::*; -pub use ::{ - tengri_input, - tengri_output, - ratatui, - crossterm, - palette, - better_panic -}; -pub(crate) use ::{ - tengri_core::*, - tengri_input::*, - tengri_output::*, - atomic_float::AtomicF64, - std::{io::{stdout, Stdout}, sync::{Arc, RwLock, atomic::{AtomicBool, Ordering::*}}}, - better_panic::{Settings, Verbosity}, - palette::{*, convert::*, okhsl::*}, - ratatui::{ - prelude::{Color, Style, Buffer}, - style::Modifier, - backend::{Backend, CrosstermBackend, ClearType}, - layout::{Size, Rect}, - buffer::Cell - }, - crossterm::{ - ExecutableCommand, - terminal::{EnterAlternateScreen, LeaveAlternateScreen, enable_raw_mode, disable_raw_mode}, - event::{Event, KeyEvent, KeyCode, KeyModifiers, KeyEventKind, KeyEventState}, - } -}; +use crate::*; -#[cfg(feature = "dsl")] use tengri_dsl::*; #[cfg(feature = "dsl")] pub fn evaluate_output_expression_tui <'a, S> ( state: &S, mut output: &mut TuiOut, expr: impl DslExpr + 'a From a933cbe2857613a439761e38a9634cf85dc17461 Mon Sep 17 00:00:00 2001 From: AAAAAAAAAAAAAAAAAAAAAAAAAAAA Date: Sat, 17 Jan 2026 03:46:24 +0200 Subject: [PATCH 3/3] fix: orphaned fn --- tui/src/lib.rs | 47 ++++++++++++++++++++++++++++++++++++------- tui/src/tui.rs | 45 ----------------------------------------- tui/src/tui_engine.rs | 44 ++++++++++++++++++++++++++++++++++++++++ tui/src/tui_test.rs | 35 -------------------------------- 4 files changed, 84 insertions(+), 87 deletions(-) delete mode 100644 tui/src/tui.rs diff --git a/tui/src/lib.rs b/tui/src/lib.rs index 081928c..39d3c59 100644 --- a/tui/src/lib.rs +++ b/tui/src/lib.rs @@ -1,8 +1,4 @@ -#![feature(type_changing_struct_update)] -#![feature(trait_alias)] -#[cfg(test)] mod tui_test; -mod tui_engine; pub use self::tui_engine::*; -mod tui_content; pub use self::tui_content::*; +#![feature(type_changing_struct_update, trait_alias)] pub use ::{tengri_input, tengri_output, ratatui, crossterm, palette, better_panic}; pub(crate) use ::{ dizzle::*, @@ -25,5 +21,42 @@ pub(crate) use ::{ event::{Event, KeyEvent, KeyCode, KeyModifiers, KeyEventKind, KeyEventState}, } }; - - +mod tui_engine; pub use self::tui_engine::*; +mod tui_content; pub use self::tui_content::*; +#[cfg(test)] mod tui_test { + use crate::*; + #[test] fn test_tui_engine () -> Usually<()> { + //use std::sync::{Arc, RwLock}; + struct TestComponent(String); + impl Content for TestComponent { + fn content (&self) -> impl Draw { + Some(self.0.as_str()) + } + } + impl Handle for TestComponent { + fn handle (&mut self, _from: &TuiIn) -> Perhaps { + Ok(None) + } + } + let engine = Tui::new()?; + engine.read().unwrap().exited.store(true, std::sync::atomic::Ordering::Relaxed); + let state = TestComponent("hello world".into()); + let _state = std::sync::Arc::new(std::sync::RwLock::new(state)); + //engine.run(&state)?; + Ok(()) + } + //#[test] fn test_parse_key () { + ////use KeyModifiers as Mods; + //let _test = |x: &str, y|assert_eq!(KeyMatcher::new(x).build(), Some(Event::Key(y))); + ////test(":x", + ////KeyEvent::new(KeyCode::Char('x'), Mods::NONE)); + ////test(":ctrl-x", + ////KeyEvent::new(KeyCode::Char('x'), Mods::CONTROL)); + ////test(":alt-x", + ////KeyEvent::new(KeyCode::Char('x'), Mods::ALT)); + ////test(":shift-x", + ////KeyEvent::new(KeyCode::Char('x'), Mods::SHIFT)); + ////test(":ctrl-alt-shift-x", + ////KeyEvent::new(KeyCode::Char('x'), Mods::CONTROL | Mods::ALT | Mods::SHIFT )); + //} +} diff --git a/tui/src/tui.rs b/tui/src/tui.rs deleted file mode 100644 index d017dff..0000000 --- a/tui/src/tui.rs +++ /dev/null @@ -1,45 +0,0 @@ -use crate::*; - -#[cfg(feature = "dsl")] -pub fn evaluate_output_expression_tui <'a, S> ( - state: &S, mut output: &mut TuiOut, expr: impl DslExpr + 'a -) -> Usually where - S: View - + for<'b>DslNs<'b, bool> - + for<'b>DslNs<'b, u16> - + for<'b>DslNs<'b, Color> -{ - // See `tengri_output::evaluate_output_expression` - let head = expr.head()?; - let mut frags = head.src()?.unwrap_or_default().split("/"); - let args = expr.tail(); - let arg0 = args.head(); - let tail0 = args.tail(); - let arg1 = tail0.head(); - let tail1 = tail0.tail(); - let arg2 = tail1.head(); - match frags.next() { - - Some("text") => if let Some(src) = args?.src()? { output.place(&src) }, - - Some("fg") => { - let arg0 = arg0?.expect("fg: expected arg 0 (color)"); - output.place(&Tui::fg( - DslNs::::from(state, arg0)?.unwrap_or_else(||panic!("fg: {arg0:?}: not a color")), - Thunk::new(move|output: &mut TuiOut|state.view(output, &arg1).unwrap()), - )) - }, - - Some("bg") => { - let arg0 = arg0?.expect("bg: expected arg 0 (color)"); - output.place(&Tui::bg( - DslNs::::from(state, arg0)?.unwrap_or_else(||panic!("bg: {arg0:?}: not a color")), - Thunk::new(move|output: &mut TuiOut|state.view(output, &arg1).unwrap()), - )) - }, - - _ => return Ok(false) - - }; - Ok(true) -} diff --git a/tui/src/tui_engine.rs b/tui/src/tui_engine.rs index 4fce13a..52a84a0 100644 --- a/tui/src/tui_engine.rs +++ b/tui/src/tui_engine.rs @@ -102,3 +102,47 @@ impl TuiRun for Arc> { Ok(()) } } + +#[cfg(feature = "dsl")] +pub fn evaluate_output_expression_tui <'a, S> ( + state: &S, mut output: &mut TuiOut, expr: impl DslExpr + 'a +) -> Usually where + S: View + + for<'b>DslNs<'b, bool> + + for<'b>DslNs<'b, u16> + + for<'b>DslNs<'b, Color> +{ + // See `tengri_output::evaluate_output_expression` + let head = expr.head()?; + let mut frags = head.src()?.unwrap_or_default().split("/"); + let args = expr.tail(); + let arg0 = args.head(); + let tail0 = args.tail(); + let arg1 = tail0.head(); + let tail1 = tail0.tail(); + let arg2 = tail1.head(); + match frags.next() { + + Some("text") => if let Some(src) = args?.src()? { output.place(&src) }, + + Some("fg") => { + let arg0 = arg0?.expect("fg: expected arg 0 (color)"); + output.place(&Tui::fg( + DslNs::::from(state, arg0)?.unwrap_or_else(||panic!("fg: {arg0:?}: not a color")), + Thunk::new(move|output: &mut TuiOut|state.view(output, &arg1).unwrap()), + )) + }, + + Some("bg") => { + let arg0 = arg0?.expect("bg: expected arg 0 (color)"); + output.place(&Tui::bg( + DslNs::::from(state, arg0)?.unwrap_or_else(||panic!("bg: {arg0:?}: not a color")), + Thunk::new(move|output: &mut TuiOut|state.view(output, &arg1).unwrap()), + )) + }, + + _ => return Ok(false) + + }; + Ok(true) +} diff --git a/tui/src/tui_test.rs b/tui/src/tui_test.rs index dbfeefd..e69de29 100644 --- a/tui/src/tui_test.rs +++ b/tui/src/tui_test.rs @@ -1,35 +0,0 @@ -use crate::*; -#[test] fn test_tui_engine () -> Usually<()> { - //use std::sync::{Arc, RwLock}; - struct TestComponent(String); - impl Content for TestComponent { - fn content (&self) -> impl Draw { - Some(self.0.as_str()) - } - } - impl Handle for TestComponent { - fn handle (&mut self, _from: &TuiIn) -> Perhaps { - Ok(None) - } - } - let engine = Tui::new()?; - engine.read().unwrap().exited.store(true, std::sync::atomic::Ordering::Relaxed); - let state = TestComponent("hello world".into()); - let _state = std::sync::Arc::new(std::sync::RwLock::new(state)); - //engine.run(&state)?; - Ok(()) -} -//#[test] fn test_parse_key () { - ////use KeyModifiers as Mods; - //let _test = |x: &str, y|assert_eq!(KeyMatcher::new(x).build(), Some(Event::Key(y))); - ////test(":x", - ////KeyEvent::new(KeyCode::Char('x'), Mods::NONE)); - ////test(":ctrl-x", - ////KeyEvent::new(KeyCode::Char('x'), Mods::CONTROL)); - ////test(":alt-x", - ////KeyEvent::new(KeyCode::Char('x'), Mods::ALT)); - ////test(":shift-x", - ////KeyEvent::new(KeyCode::Char('x'), Mods::SHIFT)); - ////test(":ctrl-alt-shift-x", - ////KeyEvent::new(KeyCode::Char('x'), Mods::CONTROL | Mods::ALT | Mods::SHIFT )); -//}