use crate::ffi;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct Point {
pub x: i32,
pub y: i32,
}
impl Point {
#[inline]
pub const fn new(x: i32, y: i32) -> Self {
Self { x, y }
}
#[inline]
pub const fn origin() -> Self {
Self { x: 0, y: 0 }
}
#[inline]
pub const fn x(&self) -> i32 {
self.x
}
#[inline]
pub const fn y(&self) -> i32 {
self.y
}
#[inline]
pub fn into_tuple(self) -> (i32, i32) {
(self.x, self.y)
}
#[inline]
pub fn from_tuple((x, y): (i32, i32)) -> Self {
Self { x, y }
}
#[doc(hidden)]
pub(crate) unsafe fn to_raw(&self) -> *mut ffi::QPoint {
ffi::QPoint_new(self.x, self.y)
}
#[inline]
pub fn is_origin(&self) -> bool {
self.x == 0 && self.y == 0
}
}
impl From<(i32, i32)> for Point {
#[inline]
fn from((x, y): (i32, i32)) -> Self {
Self { x, y }
}
}
impl From<Point> for (i32, i32) {
#[inline]
fn from(point: Point) -> Self {
(point.x, point.y)
}
}
impl std::ops::Add for Point {
type Output = Self;
#[inline]
fn add(self, other: Self) -> Self {
Self {
x: self.x + other.x,
y: self.y + other.y,
}
}
}
impl std::ops::Sub for Point {
type Output = Self;
#[inline]
fn sub(self, other: Self) -> Self {
Self {
x: self.x - other.x,
y: self.y - other.y,
}
}
}
impl std::ops::AddAssign for Point {
#[inline]
fn add_assign(&mut self, other: Self) {
self.x += other.x;
self.y += other.y;
}
}
impl std::ops::SubAssign for Point {
#[inline]
fn sub_assign(&mut self, other: Self) {
self.x -= other.x;
self.y -= other.y;
}
}
impl std::fmt::Display for Point {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Point({}, {})", self.x, self.y)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new() {
let p = Point::new(10, 20);
assert_eq!(p.x, 10);
assert_eq!(p.y, 20);
}
#[test]
fn test_origin() {
let p = Point::origin();
assert_eq!(p.x, 0);
assert_eq!(p.y, 0);
assert!(p.is_origin());
}
#[test]
fn test_from_tuple() {
let p = Point::from((30, 40));
assert_eq!(p.x, 30);
assert_eq!(p.y, 40);
}
#[test]
fn test_into_tuple() {
let p = Point::new(50, 60);
let (x, y) = p.into_tuple();
assert_eq!(x, 50);
assert_eq!(y, 60);
}
#[test]
fn test_add() {
let a = Point::new(1, 2);
let b = Point::new(3, 4);
let c = a + b;
assert_eq!(c.x, 4);
assert_eq!(c.y, 6);
}
#[test]
fn test_sub() {
let a = Point::new(5, 7);
let b = Point::new(2, 3);
let c = a - b;
assert_eq!(c.x, 3);
assert_eq!(c.y, 4);
}
#[test]
fn test_display() {
let p = Point::new(10, 20);
assert_eq!(format!("{}", p), "Point(10, 20)");
}
}