add more proptests for output

This commit is contained in:
🪞👃🪞 2025-01-27 18:41:27 +01:00
parent c78dd2453a
commit 2e18ca96fd
9 changed files with 154 additions and 78 deletions

View file

@ -6,6 +6,17 @@ pub trait Area<N: Coordinate>: From<[N;4]> + Debug + Copy {
fn y (&self) -> N;
fn w (&self) -> N;
fn h (&self) -> N;
#[inline] fn zero () -> [N;4] {
[N::zero(), N::zero(), N::zero(), N::zero()]
}
#[inline] fn from_position (pos: impl Size<N>) -> [N;4] {
let [x, y] = pos.wh();
[x, y, 0.into(), 0.into()]
}
#[inline] fn from_size (size: impl Size<N>) -> [N;4] {
let [w, h] = size.wh();
[0.into(), 0.into(), w, h]
}
#[inline] fn expect_min (&self, w: N, h: N) -> Usually<&Self> {
if self.w() < w || self.h() < h {
Err(format!("min {w}x{h}").into())
@ -49,14 +60,13 @@ pub trait Area<N: Coordinate>: From<[N;4]> + Debug + Copy {
#[inline] fn center (&self) -> [N;2] {
[self.x().plus(self.w()/2.into()), self.y().plus(self.h()/2.into())]
}
#[inline] fn center_x (&self, n: N) -> [N;4] {
let [x, y, w, h] = self.xywh();
[(x.plus(w / 2.into())).minus(n / 2.into()), y.plus(h / 2.into()), n, 1.into()]
}
#[inline] fn center_y (&self, n: N) -> [N;4] {
let [x, y, w, h] = self.xywh();
[x.plus(w / 2.into()), (y + h / 2.into()).minus(n / 2.into()), 1.into(), n]
[x.plus(w / 2.into()), (y.plus(h / 2.into())).minus(n / 2.into()), 1.into(), n]
}
#[inline] fn center_xy (&self, [n, m]: [N;2]) -> [N;4] {
let [x, y, w, h] = self.xywh();
@ -66,17 +76,6 @@ pub trait Area<N: Coordinate>: From<[N;4]> + Debug + Copy {
#[inline] fn centered (&self) -> [N;2] {
[self.x().minus(self.w()/2.into()), self.y().minus(self.h()/2.into())]
}
#[inline] fn zero () -> [N;4] {
[N::zero(), N::zero(), N::zero(), N::zero()]
}
#[inline] fn from_position (pos: impl Size<N>) -> [N;4] {
let [x, y] = pos.wh();
[x, y, 0.into(), 0.into()]
}
#[inline] fn from_size (size: impl Size<N>) -> [N;4] {
let [w, h] = size.wh();
[0.into(), 0.into(), w, h]
}
}
impl<N: Coordinate> Area<N> for (N, N, N, N) {
@ -92,3 +91,40 @@ impl<N: Coordinate> Area<N> for [N;4] {
#[inline] fn w (&self) -> N { self[2] }
#[inline] fn h (&self) -> N { self[3] }
}
#[cfg(test)] mod test_area {
use super::*;
use proptest::prelude::*;
proptest! {
#[test] fn test_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();
}
}
}

33
output/src/direction.rs Normal file
View file

@ -0,0 +1,33 @@
use crate::*;
/// A cardinal direction.
#[derive(Copy, Clone, PartialEq)]
pub enum Direction { North, South, East, West, Above, Below }
impl Direction {
pub fn split_fixed <N: Coordinate> (self, area: impl Area<N>, a: N) -> ([N;4],[N;4]) {
let [x, y, w, h] = area.xywh();
match self {
North => ([x, y.plus(h).minus(a), w, a], [x, y, w, h.minus(a)]),
South => ([x, y, w, a], [x, y.plus(a), w, h.minus(a)]),
East => ([x, y, a, h], [x.plus(a), y, w.minus(a), h]),
West => ([x.plus(w).minus(a), y, a, h], [x, y, w.minus(a), h]),
Above | Below => (area.xywh(), area.xywh())
}
}
}
#[cfg(test)] mod test_op_transform {
use super::*;
use proptest::prelude::*;
proptest! {
#[test] fn test_direction (
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,
) {
for d in [North, South, East, West, Above, Below].iter() {
let _ = d.split_fixed([x, y, w, h], a);
}
}
}
}

View file

@ -1,6 +1,7 @@
//#![feature(lazy_type_alias)]
#![feature(type_alias_impl_trait)]
#![feature(impl_trait_in_assoc_type)]
mod direction; pub use self::direction::*;
mod coordinate; pub use self::coordinate::*;
mod size; pub use self::size::*;
mod area; pub use self::area::*;

View file

@ -1,20 +1,5 @@
use crate::*;
pub use self::Direction::*;
/// A cardinal direction.
#[derive(Copy, Clone, PartialEq)]
pub enum Direction { North, South, East, West, Above, Below }
impl Direction {
pub fn split_fixed <N: Coordinate> (self, area: impl Area<N>, a: N) -> ([N;4],[N;4]) {
let [x, y, w, h] = area.xywh();
match self {
North => ([x, (y+h).minus(a), w, a], [x, y, w, h.minus(a)]),
South => ([x, y, w, a], [x, y + a, w, h.minus(a)]),
East => ([x, y, a, h], [x + a, y, w.minus(a), h]),
West => ([(x+w).minus(a), y, a, h], [x, y, w - a, h]),
Above | Below => (area.xywh(), area.xywh())
}
}
}
pub use Direction::*;
/// A split or layer.
pub struct Bsp<X, Y>(Direction, X, Y);
impl<E: Output, A: Content<E>, B: Content<E>> Content<E> for Bsp<A, B> {

View file

@ -38,3 +38,26 @@ impl<N: Coordinate> Size<N> for [N;2] {
#[inline] fn x (&self) -> N { self[0] }
#[inline] fn y (&self) -> N { self[1] }
}
#[cfg(test)] mod test_size {
use super::*;
use proptest::prelude::*;
proptest! {
#[test] fn test_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();
}
}
}