embedded_graphics/geometry/
size.rsuse crate::geometry::Point;
use core::ops::{Add, AddAssign, Div, DivAssign, Index, Mul, MulAssign, Sub, SubAssign};
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)]
pub struct Size {
pub width: u32,
pub height: u32,
}
impl Size {
pub const fn new(width: u32, height: u32) -> Self {
Size { width, height }
}
pub const fn zero() -> Self {
Size {
width: 0,
height: 0,
}
}
pub(crate) fn from_bounding_box(corner_1: Point, corner_2: Point) -> Self {
let width = (corner_1.x - corner_2.x).abs() as u32;
let height = (corner_1.y - corner_2.y).abs() as u32;
Self { width, height }
}
}
impl Add for Size {
type Output = Size;
fn add(self, other: Size) -> Size {
Size::new(self.width + other.width, self.height + other.height)
}
}
impl AddAssign for Size {
fn add_assign(&mut self, other: Size) {
self.width += other.width;
self.height += other.height;
}
}
impl Sub for Size {
type Output = Size;
fn sub(self, other: Size) -> Size {
Size::new(self.width - other.width, self.height - other.height)
}
}
impl SubAssign for Size {
fn sub_assign(&mut self, other: Size) {
self.width -= other.width;
self.height -= other.height;
}
}
impl Mul<u32> for Size {
type Output = Size;
fn mul(self, rhs: u32) -> Size {
Size::new(self.width * rhs, self.height * rhs)
}
}
impl MulAssign<u32> for Size {
fn mul_assign(&mut self, rhs: u32) {
self.width *= rhs;
self.height *= rhs;
}
}
impl Div<u32> for Size {
type Output = Size;
fn div(self, rhs: u32) -> Size {
Size::new(self.width / rhs, self.height / rhs)
}
}
impl DivAssign<u32> for Size {
fn div_assign(&mut self, rhs: u32) {
self.width /= rhs;
self.height /= rhs;
}
}
impl Index<usize> for Size {
type Output = u32;
fn index(&self, idx: usize) -> &u32 {
match idx {
0 => &self.width,
1 => &self.height,
_ => panic!("index out of bounds: the len is 2 but the index is {}", idx),
}
}
}
impl From<(u32, u32)> for Size {
fn from(other: (u32, u32)) -> Self {
Size::new(other.0, other.1)
}
}
impl From<[u32; 2]> for Size {
fn from(other: [u32; 2]) -> Self {
Size::new(other[0], other[1])
}
}
impl From<&[u32; 2]> for Size {
fn from(other: &[u32; 2]) -> Self {
Size::new(other[0], other[1])
}
}
impl From<Size> for (u32, u32) {
fn from(other: Size) -> (u32, u32) {
(other.width, other.height)
}
}
impl From<Size> for [u32; 2] {
fn from(other: Size) -> [u32; 2] {
[other.width, other.height]
}
}
impl From<&Size> for (u32, u32) {
fn from(other: &Size) -> (u32, u32) {
(other.width, other.height)
}
}
#[cfg(feature = "nalgebra_support")]
use nalgebra::{base::Scalar, Vector2};
#[cfg(feature = "nalgebra_support")]
impl<N> From<Vector2<N>> for Size
where
N: Into<u32> + Scalar,
{
fn from(other: Vector2<N>) -> Self {
Self::new(other[0].into(), other[1].into())
}
}
#[cfg(feature = "nalgebra_support")]
impl<N> From<&Vector2<N>> for Size
where
N: Into<u32> + Scalar,
{
fn from(other: &Vector2<N>) -> Self {
Self::new(other[0].into(), other[1].into())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn sizes_can_be_added() {
let left = Size::new(10, 20);
let right = Size::new(30, 40);
assert_eq!(left + right, Size::new(40, 60));
}
#[test]
fn sizes_can_be_subtracted() {
let left = Size::new(30, 40);
let right = Size::new(10, 20);
assert_eq!(left - right, Size::new(20, 20));
}
#[test]
fn sizes_can_be_multiplied_by_scalar() {
let s = Size::new(1, 2);
assert_eq!(s * 3, Size::new(3, 6));
let mut s = Size::new(2, 3);
s *= 4;
assert_eq!(s, Size::new(8, 12));
}
#[test]
fn sizes_can_be_divided_by_scalar() {
let s = Size::new(10, 20);
assert_eq!(s / 2, Size::new(5, 10));
let mut s = Size::new(20, 30);
s /= 5;
assert_eq!(s, Size::new(4, 6));
}
#[test]
fn from_tuple() {
assert_eq!(Size::from((20, 30)), Size::new(20, 30));
}
#[test]
fn from_array() {
assert_eq!(Size::from([20, 30]), Size::new(20, 30));
}
#[test]
fn to_array() {
let array: [u32; 2] = Size::new(20, 30).into();
assert_eq!(array, [20, 30]);
}
#[test]
fn from_array_ref() {
assert_eq!(Size::from(&[20, 30]), Size::new(20, 30));
}
#[test]
fn index() {
let size = Size::new(1, 2);
assert_eq!(size.width, size[0]);
assert_eq!(size.height, size[1]);
}
#[test]
#[should_panic]
fn index_out_of_bounds() {
let size = Size::new(1, 2);
let _ = size[2];
}
#[test]
#[cfg(feature = "nalgebra_support")]
fn nalgebra_support() {
let left = nalgebra::Vector2::new(30u32, 40);
let right = nalgebra::Vector2::new(10, 20);
assert_eq!(Size::from(left - right), Size::new(20, 20));
}
}