use std::fmt::Display;
use std::ops::{Add, AddAssign, Sub, SubAssign};
#[derive(Clone, Copy, PartialEq, Debug, PartialOrd, Default)]
#[cfg_attr(feature = "ffi", repr(C))]
pub struct Size {
pub width: f32,
pub height: f32,
}
impl Size {
pub const fn new(width: f32, height: f32) -> Size {
Self { width, height }
}
pub const fn unit(value: f32) -> Size {
Self::new(value, value)
}
}
impl Add for Size {
type Output = Size;
fn add(self, rhs: Self) -> Self::Output {
Self {
width: self.width + rhs.width,
height: self.height + rhs.height,
}
}
}
impl Add<f32> for Size {
type Output = Size;
fn add(self, rhs: f32) -> Self::Output {
Self {
width: self.width + rhs,
height: self.height + rhs,
}
}
}
impl Sub for Size {
type Output = Size;
fn sub(self, rhs: Self) -> Self::Output {
Self {
width: self.width - rhs.width,
height: self.height - rhs.height,
}
}
}
impl Sub<f32> for Size {
type Output = Size;
fn sub(self, rhs: f32) -> Self::Output {
Self {
width: self.width - rhs,
height: self.height - rhs,
}
}
}
impl AddAssign for Size {
fn add_assign(&mut self, other: Self) {
self.width += other.width;
self.height += other.height;
}
}
impl AddAssign<f32> for Size {
fn add_assign(&mut self, other: f32) {
self.width += other;
self.height += other;
}
}
impl SubAssign for Size {
fn sub_assign(&mut self, other: Self) {
self.width -= other.width;
self.height -= other.height;
}
}
impl SubAssign<f32> for Size {
fn sub_assign(&mut self, other: f32) {
self.width -= other;
self.height -= other;
}
}
impl From<(f32, f32)> for Size {
fn from((width, height): (f32, f32)) -> Self {
Self { width, height }
}
}
impl Display for Size {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(prec) = f.precision() {
write!(f, "{:.prec$}x{:.prec$}", self.width, self.height)
} else {
write!(f, "{}x{}", self.width, self.height)
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn display() {
let size = Size::new(50.0, 20.24242);
let string = format!("{size}");
assert_eq!(string, "50x20.24242");
}
#[test]
fn display_with_precision() {
let size = Size::new(50.0, 20.24242);
let string = format!("{size:.1}");
assert_eq!(string, "50.0x20.2");
}
}