#[derive(Debug, Clone)]
struct Point {
    x: i32,
    y: i32,
}

impl std::ops::Add<Point> for Point {
    type Output = Self;

    fn add(self, rhs: Self) -> Self {
        Point {
            x: self.x + rhs.x,
            y: self.y + rhs.y,
        }
    }
}

impl std::ops::Sub<Point> for Point {
    type Output = Self;

    fn sub(self, rhs: Self) -> Self {
        Point {
            x: self.x - rhs.x,
            y: self.y - rhs.y,
        }
    }
}

impl std::ops::Mul<Point> for Point {
    type Output = Self;

    fn mul(self, rhs: Self) -> Self {
        Point {
            x: self.x * rhs.x,
            y: self.y * rhs.y,
        }
    }
}

impl std::ops::Div<Point> for Point {
    type Output = Self;

    fn div(self, rhs: Self) -> Self {
        Point {
            x: self.x / rhs.x,
            y: self.y / rhs.y,
        }
    }
}

fn main() {
    let a = Point { x: 2, y: 3, };
    let b = Point { x: 4, y: 5, };
    let c = a.clone() + b.clone();
    let d = a.clone() - b.clone();
    let e = a.clone() * b.clone();
    let f = a.clone() / b.clone();
    println!("{:?}", a);
    println!("{:?}", b);
    println!("{:?}", c);
    println!("{:?}", d);
    println!("{:?}", e);
    println!("{:?}", f);
}
