refactor: extract dizzle

This commit is contained in:
AAAAAAAAAAAAAAAAAAAAAAAAAAAA 2026-01-17 03:43:27 +02:00
parent b0d2fad17b
commit 1344967f33
34 changed files with 372 additions and 2235 deletions

View file

@ -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 }

200
output/src/lib.rs Normal file
View file

@ -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<u16>>::zero();
let _: [u16;4] = <[u16;4] as Area<u16>>::from_position([a, b]);
let _: [u16;4] = <[u16;4] as Area<u16>>::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 <T: Draw<Self> + ?Sized> (&mut self, area: [u16;4], _: &T) {
println!("place_at: {area:?}");
()
}
}
impl Draw<TestOut> 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<T: Out> Content<T> for Foo {}
fn _make_map <T: Out, U: Content<T> + Send + Sync> (data: &Vec<U>) -> impl Draw<T> {
Map::new(||data.iter(), |_foo, _index|{})
}
let _data = vec![Foo, Foo, Foo];
//let map = make_map(&data);
}
}

View file

@ -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::*;

View file

@ -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<u16>>::zero();
let _: [u16;4] = <[u16;4] as Area<u16>>::from_position([a, b]);
let _: [u16;4] = <[u16;4] as Area<u16>>::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 <T: Draw<Self> + ?Sized> (&mut self, area: [u16;4], _: &T) {
println!("place_at: {area:?}");
()
}
}
impl Draw<TestOut> 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<T: Out> Content<T> for Foo {}
fn _make_map <T: Out, U: Content<T> + Send + Sync> (data: &Vec<U>) -> impl Draw<T> {
Map::new(||data.iter(), |_foo, _index|{})
}
let _data = vec![Foo, Foo, Foo];
//let map = make_map(&data);
}

View file

@ -1,5 +1,5 @@
use crate::*;
use ::tengri_dsl::{Dsl, DslExpr, DslWord, DslNs};
use ::dizzle::{Dsl, DslExpr, DslWord, DslNs};
pub trait View<O, U> {
fn view_expr <'a> (&'a self, output: &mut O, expr: &'a impl DslExpr) -> Usually<U> {