flatten workspace into 1 crate

This commit is contained in:
🪞👃🪞 2024-12-29 00:10:30 +01:00
parent 7c4e1e2166
commit d926422c67
147 changed files with 66 additions and 126 deletions

236
src/space.rs Normal file
View file

@ -0,0 +1,236 @@
use crate::*;
use std::ops::{Add, Sub, Mul, Div};
use std::fmt::{Display, Debug};
// TODO: return impl Point and impl Size instead of [N;x]
// to disambiguate between usage of 2-"tuple"s
//////////////////////////////////////////////////////
pub(crate) mod align;
pub(crate) mod bsp;
pub(crate) mod cond; pub(crate) use cond::*;
pub(crate) mod fill;
pub(crate) mod fixed; pub(crate) use fixed::*;
pub(crate) mod inset_outset; pub(crate) use inset_outset::*;
pub(crate) mod layers; pub(crate) use layers::*;
pub(crate) mod measure; pub(crate) use measure::*;
pub(crate) mod min_max; pub(crate) use min_max::*;
pub(crate) mod push_pull; pub(crate) use push_pull::*;
pub(crate) mod scroll;
pub(crate) mod shrink_grow; pub(crate) use shrink_grow::*;
pub(crate) mod split; pub(crate) use split::*;
pub(crate) mod stack; pub(crate) use stack::*;
pub use self::{
align::*,
bsp::*,
fill::*,
};
#[derive(Copy, Clone, PartialEq)]
pub enum Direction { North, South, West, East, }
impl Direction {
pub fn is_north (&self) -> bool { matches!(self, Self::North) }
pub fn is_south (&self) -> bool { matches!(self, Self::South) }
pub fn is_east (&self) -> bool { matches!(self, Self::West) }
pub fn is_west (&self) -> bool { matches!(self, Self::East) }
/// Return next direction clockwise
pub fn cw (&self) -> Self {
match self {
Self::North => Self::East,
Self::South => Self::West,
Self::West => Self::North,
Self::East => Self::South,
}
}
/// Return next direction counterclockwise
pub fn ccw (&self) -> Self {
match self {
Self::North => Self::West,
Self::South => Self::East,
Self::West => Self::South,
Self::East => Self::North,
}
}
}
/// Standard numeric type.
pub trait Coordinate: Send + Sync + Copy
+ Add<Self, Output=Self>
+ Sub<Self, Output=Self>
+ Mul<Self, Output=Self>
+ Div<Self, Output=Self>
+ Ord + PartialEq + Eq
+ Debug + Display + Default
+ From<u16> + Into<u16>
+ Into<usize>
+ Into<f64>
{
fn minus (self, other: Self) -> Self {
if self >= other {
self - other
} else {
0.into()
}
}
fn zero () -> Self {
0.into()
}
}
impl<T> Coordinate for T where T: Send + Sync + Copy
+ Add<Self, Output=Self>
+ Sub<Self, Output=Self>
+ Mul<Self, Output=Self>
+ Div<Self, Output=Self>
+ Ord + PartialEq + Eq
+ Debug + Display + Default
+ From<u16> + Into<u16>
+ Into<usize>
+ Into<f64>
{}
pub trait Size<N: Coordinate> {
fn x (&self) -> N;
fn y (&self) -> N;
#[inline] fn w (&self) -> N { self.x() }
#[inline] fn h (&self) -> N { self.y() }
#[inline] fn wh (&self) -> [N;2] { [self.x(), self.y()] }
#[inline] fn clip_w (&self, w: N) -> [N;2] { [self.w().min(w), self.h()] }
#[inline] fn clip_h (&self, h: N) -> [N;2] { [self.w(), self.h().min(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())
} else {
Ok(self)
}
}
}
impl<N: Coordinate> Size<N> for (N, N) {
fn x (&self) -> N { self.0 }
fn y (&self) -> N { self.1 }
}
impl<N: Coordinate> Size<N> for [N;2] {
fn x (&self) -> N { self[0] }
fn y (&self) -> N { self[1] }
}
pub trait Area<N: Coordinate>: Copy {
fn x (&self) -> N;
fn y (&self) -> N;
fn w (&self) -> N;
fn h (&self) -> N;
fn x2 (&self) -> N { self.x() + self.w() }
fn y2 (&self) -> N { self.y() + self.h() }
#[inline] fn wh (&self) -> [N;2] { [self.w(), self.h()] }
#[inline] fn xywh (&self) -> [N;4] { [self.x(), self.y(), self.w(), self.h()] }
#[inline] fn lrtb (&self) -> [N;4] { [self.x(), self.x2(), self.y(), self.y2()] }
#[inline] fn push_x (&self, x: N) -> [N;4] { [self.x() + x, self.y(), self.w(), self.h()] }
#[inline] fn push_y (&self, y: N) -> [N;4] { [self.x(), self.y() + y, self.w(), self.h()] }
#[inline] fn shrink_x (&self, x: N) -> [N;4] {
[self.x(), self.y(), self.w().minus(x), self.h()]
}
#[inline] fn shrink_y (&self, y: N) -> [N;4] {
[self.x(), self.y(), self.w(), self.h().minus(y)]
}
#[inline] fn set_w (&self, w: N) -> [N;4] { [self.x(), self.y(), w, self.h()] }
#[inline] fn set_h (&self, h: N) -> [N;4] { [self.x(), self.y(), self.w(), h] }
#[inline] fn clip_h (&self, h: N) -> [N;4] {
[self.x(), self.y(), self.w(), self.h().min(h)]
}
#[inline] fn clip_w (&self, w: N) -> [N;4] {
[self.x(), self.y(), self.w().min(w), self.h()]
}
#[inline] fn clip (&self, wh: impl Size<N>) -> [N;4] {
[self.x(), self.y(), wh.w(), wh.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())
} else {
Ok(self)
}
}
#[inline] fn split_fixed (&self, direction: Direction, a: N) -> ([N;4],[N;4]) {
match direction {
Direction::North => (
[self.x(), (self.y()+self.h()).minus(a), self.w(), a],
[self.x(), self.y(), self.w(), self.h().minus(a)],
),
Direction::South => (
[self.x(), self.y(), self.w(), a],
[self.x(), self.y() + a, self.w(), self.h().minus(a)],
),
Direction::East => (
[self.x(), self.y(), a, self.h()],
[self.x() + a, self.y(), self.w().minus(a), self.h()],
),
Direction::West => (
[self.x() + self.w() - a, self.y(), a, self.h()],
[self.x(), self.y(), self.w() - a, self.h()],
),
}
}
}
impl<N: Coordinate> Area<N> for (N, N, N, N) {
#[inline] fn x (&self) -> N { self.0 }
#[inline] fn y (&self) -> N { self.1 }
#[inline] fn w (&self) -> N { self.2 }
#[inline] fn h (&self) -> N { self.3 }
}
impl<N: Coordinate> Area<N> for [N;4] {
#[inline] fn x (&self) -> N { self[0] }
#[inline] fn y (&self) -> N { self[1] }
#[inline] fn w (&self) -> N { self[2] }
#[inline] fn h (&self) -> N { self[3] }
}
#[macro_export] macro_rules! col {
([$($expr:expr),* $(,)?]) => {
Stack::down(move|add|{ $(add(&$expr)?;)* Ok(()) })
};
(![$($expr:expr),* $(,)?]) => {
Stack::down(|add|{ $(add(&$expr)?;)* Ok(()) })
};
($expr:expr) => {
Stack::down($expr)
};
($pat:pat in $collection:expr => $item:expr) => {
Stack::down(move|add|{ for $pat in $collection { add(&$item)?; } Ok(()) })
};
}
#[macro_export] macro_rules! col_up {
([$($expr:expr),* $(,)?]) => {
Stack::up(move|add|{ $(add(&$expr)?;)* Ok(()) })
};
(![$($expr:expr),* $(,)?]) => {
Stack::up(|add|{ $(add(&$expr)?;)* Ok(()) })
};
($expr:expr) => {
Stack::up(expr)
};
($pat:pat in $collection:expr => $item:expr) => {
Stack::up(move |add|{ for $pat in $collection { add(&$item)?; } Ok(()) })
};
}
#[macro_export] macro_rules! row {
([$($expr:expr),* $(,)?]) => {
Stack::right(move|add|{ $(add(&$expr)?;)* Ok(()) })
};
(![$($expr:expr),* $(,)?]) => {
Stack::right(|add|{ $(add(&$expr)?;)* Ok(()) })
};
($expr:expr) => {
Stack::right($expr)
};
($pat:pat in $collection:expr => $item:expr) => {
Stack::right(move|add|{ for $pat in $collection { add(&$item)?; } Ok(()) })
};
}