diff --git a/output/src/lib.rs b/output/src/lib.rs index 2b12b04..6b2946a 100644 --- a/output/src/lib.rs +++ b/output/src/lib.rs @@ -1,63 +1,15 @@ #![feature(step_trait)] #![feature(type_alias_impl_trait)] #![feature(impl_trait_in_assoc_type)] -//#![feature(impl_trait_in_fn_trait_return)] - +pub(crate) use tengri_core::*; +pub(crate) use std::marker::PhantomData; +#[cfg(feature = "dsl")] pub(crate) use ::tengri_dsl::*; mod space; pub use self::space::*; mod ops; pub use self::ops::*; mod output; pub use self::output::*; - -pub(crate) use tengri_core::*; -pub(crate) use std::marker::PhantomData; - -#[cfg(feature = "dsl")] pub(crate) use ::tengri_dsl::*; -#[cfg(feature = "dsl")] mod view; -#[cfg(feature = "dsl")] pub use self::view::*; - -#[cfg(test)] use proptest_derive::Arbitrary; - -#[cfg(test)] #[test] fn test_stub_output () -> Usually<()> { - use crate::*; - struct TestOutput([u16;4]); - impl Output for TestOutput { - 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 (&mut self, _: [u16;4], _: &impl Render) { - () - } - } - impl Content for String { - fn render (&self, to: &mut TestOutput) { - to.area_mut().set_w(self.len() as u16); - } - } - Ok(()) -} - -#[cfg(test)] #[test] fn test_space () { - use crate::*; - assert_eq!(Area::center(&[10u16, 10, 20, 20]), [20, 20]); -} - -#[cfg(test)] #[test] fn test_iter_map () { - struct Foo; - impl Content for Foo {} - fn make_map + Send + Sync> (data: &Vec) -> impl Content { - Map::new(||data.iter(), |foo, index|{}) - } - let data = vec![Foo, Foo, Foo]; - //let map = make_map(&data); -} - #[cfg(test)] mod test { use crate::*; + use proptest_derive::Arbitrary; use proptest::{prelude::*, option::of}; proptest! { @@ -187,4 +139,44 @@ pub(crate) use std::marker::PhantomData; } } + #[test] fn test_stub_output () -> Usually<()> { + use crate::*; + struct TestOutput([u16;4]); + impl Output for TestOutput { + 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 (&mut self, _: [u16;4], _: &impl Render) { + () + } + } + impl Content for String { + fn render (&self, to: &mut TestOutput) { + 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 Content { + Map::new(||data.iter(), |foo, index|{}) + } + let data = vec![Foo, Foo, Foo]; + //let map = make_map(&data); + } + } diff --git a/output/src/ops/bsp.rs b/output/src/ops/bsp.rs index 6062485..8e1d8e9 100644 --- a/output/src/ops/bsp.rs +++ b/output/src/ops/bsp.rs @@ -21,35 +21,29 @@ impl, B: Content> Content for Bsp { } } #[cfg(feature = "dsl")] -from_dsl!(@ab: Bsp: |state, iter|Ok(if let Some(Token { - value: Value::Key("bsp/n"|"bsp/s"|"bsp/e"|"bsp/w"|"bsp/a"|"bsp/b"), - .. -}) = iter.peek() { - let base = iter.clone(); - return Ok(Some(match iter.next() { - Some(Token { value: Value::Key("bsp/n"), .. }) => - Self::n(state.take_or_fail(iter, "expected content 1")?, - state.take_or_fail(iter, "expected content 2")?), - Some(Token { value: Value::Key("bsp/s"), .. }) => - Self::s(state.take_or_fail(iter, "expected content 1")?, - state.take_or_fail(iter, "expected content 2")?), - Some(Token { value: Value::Key("bsp/e"), .. }) => - Self::e(state.take_or_fail(iter, "expected content 1")?, - state.take_or_fail(iter, "expected content 2")?), - Some(Token { value: Value::Key("bsp/w"), .. }) => - Self::w(state.take_or_fail(iter, "expected content 1")?, - state.take_or_fail(iter, "expected content 2")?), - Some(Token { value: Value::Key("bsp/a"), .. }) => - Self::a(state.take_or_fail(iter, "expected content 1")?, - state.take_or_fail(iter, "expected content 2")?), - Some(Token { value: Value::Key("bsp/b"), .. }) => - Self::b(state.take_or_fail(iter, "expected content 1")?, - state.take_or_fail(iter, "expected content 2")?), - _ => unreachable!(), - })) -} else { - None -})); +impl + Dsl + std::fmt::Debug, A, B> Namespace for Bsp { + fn take_from <'source> (state: &State, words: &mut TokenIter<'source>) -> Perhaps { + Ok(if let Some(Token { + value: Value::Key("bsp/n"|"bsp/s"|"bsp/e"|"bsp/w"|"bsp/a"|"bsp/b"), + .. + }) = words.peek() { + let base = words.clone(); + let a: A = state.take_or_fail(words, "expected content 1")?; + let b: B = state.take_or_fail(words, "expected content 2")?; + return Ok(Some(match words.next() { + Some(Token { value: Value::Key("bsp/n"), .. }) => Self::n(a, b), + Some(Token { value: Value::Key("bsp/s"), .. }) => Self::s(a, b), + Some(Token { value: Value::Key("bsp/e"), .. }) => Self::e(a, b), + Some(Token { value: Value::Key("bsp/w"), .. }) => Self::w(a, b), + Some(Token { value: Value::Key("bsp/a"), .. }) => Self::a(a, b), + Some(Token { value: Value::Key("bsp/b"), .. }) => Self::b(a, b), + _ => unreachable!(), + })) + } else { + None + }) + } +} impl Bsp { #[inline] pub const fn n (a: A, b: B) -> Self { Self(North, a, b) } #[inline] pub const fn s (a: A, b: B) -> Self { Self(South, a, b) } diff --git a/output/src/test.rs b/output/src/test.rs new file mode 100644 index 0000000..517aa64 --- /dev/null +++ b/output/src/test.rs @@ -0,0 +1,170 @@ +use crate::*; +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)), + (Some(y), None) => Some($Op::y(y, content)), + _ => None + } { + assert_eq!(Content::layout(&op, [x, y, w, h]), + Render::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_margin, Margin); +test_op_transform!(proptest_op_padding, Padding); + +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]), + Render::layout(&bsp, [x, y, w, h]), + ); + } +} + +#[test] fn test_stub_output () -> Usually<()> { + use crate::*; + struct TestOutput([u16;4]); + impl Output for TestOutput { + 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 (&mut self, _: [u16;4], _: &impl Render) { + () + } + } + impl Content for String { + fn render (&self, to: &mut TestOutput) { + 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 Content { + 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 deleted file mode 100644 index ae252d9..0000000 --- a/output/src/view.rs +++ /dev/null @@ -1,54 +0,0 @@ -use crate::*; - -//#[cfg(feature = "dsl")] -//#[macro_export] macro_rules! try_delegate { - //($s:ident, $dsl:expr, $T:ty) => { - //let value: Option<$T> = Dsl::take_from($s, $dsl)?; - //if let Some(value) = value { - //return Ok(Some(value.boxed())) - //} - //} -//} - -//// Provides components to the view. -//#[cfg(feature = "dsl")] -//pub trait ViewContext<'state, E: Output + 'state>: - //Namespace + Namespace + Namespace + Send + Sync -//{ - //fn get_content_sym <'source: 'state> (&'state self, iter: &mut TokenIter<'source>) - //-> Perhaps>; - //fn get_content_exp <'source: 'state> (&'state self, iter: &mut TokenIter<'source>) - //-> Perhaps> - //{ - //try_delegate!(self, iter, When::>); - //try_delegate!(self, iter, Either::, RenderBox<'state, E>>); - //try_delegate!(self, iter, Align::>); - //try_delegate!(self, iter, Bsp::, RenderBox<'state, E>>); - //try_delegate!(self, iter, Fill::>); - //try_delegate!(self, iter, Fixed::<_, RenderBox<'state, E>>); - //try_delegate!(self, iter, Min::<_, RenderBox<'state, E>>); - //try_delegate!(self, iter, Max::<_, RenderBox<'state, E>>); - //try_delegate!(self, iter, Shrink::<_, RenderBox<'state, E>>); - //try_delegate!(self, iter, Expand::<_, RenderBox<'state, E>>); - //try_delegate!(self, iter, Push::<_, RenderBox<'state, E>>); - //try_delegate!(self, iter, Pull::<_, RenderBox<'state, E>>); - //try_delegate!(self, iter, Margin::<_, RenderBox<'state, E>>); - //try_delegate!(self, iter, Padding::<_, RenderBox<'state, E>>); - //Ok(None) - //} -//} - -//#[cfg(feature = "dsl")] -//impl<'context, O: Output + 'context, T: ViewContext<'context, O>> Namespace for RenderBox<'context, O> { - //fn take_from <'state, 'source: 'state> (state: &'state T, token: &mut TokenIter<'source>) - //-> Perhaps> - //{ - //Ok(if let Some(content) = state.get_content_sym(token)? { - //Some(content) - //} else if let Some(content) = state.get_content_exp(token)? { - //Some(content) - //} else { - //None - //}) - //} -//}