kittycad 0.4.10

A fully generated & opinionated API client for the KittyCAD API.
Documentation
//! Manually implement methods and traits that cannot be autogenerated.

use std::ops::{Add, Div, Mul, Sub};

use crate::types::{Angle, Point2D, Point3D, UnitAngle};

impl Copy for UnitAngle {}
impl Copy for Angle {}
impl Copy for Point2D {}
impl Copy for Point3D {}

impl Angle {
    /// An angle of size 0.
    pub const ZERO: Self = Self {
        unit: UnitAngle::Degrees,
        value: 0.0,
    };

    /// Make a new angle in degrees
    pub fn from_degrees(size: f64) -> Self {
        Self {
            unit: UnitAngle::Degrees,
            value: size,
        }
    }
    /// Make a new angle in radians
    pub fn from_radians(size: f64) -> Self {
        Self {
            unit: UnitAngle::Radians,
            value: size,
        }
    }

    /// Get the size of the angle, in radians
    pub fn radians(&self) -> f64 {
        match self.unit {
            UnitAngle::Radians => self.value,
            UnitAngle::Degrees => self.value.to_radians(),
        }
    }

    /// Get the size of the angle, in degrees
    pub fn degrees(&self) -> f64 {
        match self.unit {
            UnitAngle::Degrees => self.value,
            UnitAngle::Radians => self.value.to_degrees(),
        }
    }
}

impl std::ops::AddAssign for Angle {
    fn add_assign(&mut self, rhs: Self) {
        match self.unit {
            UnitAngle::Degrees => self.value += rhs.degrees(),
            UnitAngle::Radians => self.value += rhs.radians(),
        }
    }
}

impl std::ops::Add for Angle {
    type Output = Self;

    fn add(self, rhs: Self) -> Self::Output {
        Self {
            unit: UnitAngle::Degrees,
            value: self.degrees() + rhs.degrees(),
        }
    }
}

impl std::ops::SubAssign for Angle {
    fn sub_assign(&mut self, rhs: Self) {
        match self.unit {
            UnitAngle::Degrees => self.value -= rhs.degrees(),
            UnitAngle::Radians => self.value -= rhs.radians(),
        }
    }
}

impl std::ops::Sub for Angle {
    type Output = Self;

    fn sub(self, rhs: Self) -> Self::Output {
        Self {
            unit: UnitAngle::Degrees,
            value: self.degrees() - rhs.degrees(),
        }
    }
}

impl From<[f64; 2]> for Point2D {
    fn from([x, y]: [f64; 2]) -> Self {
        Self { x, y }
    }
}

impl From<&[f64; 2]> for Point2D {
    fn from(p: &[f64; 2]) -> Self {
        let [x, y] = *p;
        Self { x, y }
    }
}

impl From<Point2D> for [f64; 2] {
    fn from(Point2D { x, y }: Point2D) -> Self {
        [x, y]
    }
}

impl Add<f64> for Point2D {
    type Output = Self;

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

impl Sub<f64> for Point2D {
    type Output = Self;

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

impl Mul<f64> for Point2D {
    type Output = Self;

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

impl Div<f64> for Point2D {
    type Output = Self;

    fn div(self, rhs: f64) -> Self::Output {
        Self {
            x: self.x / rhs,
            y: self.y / rhs,
        }
    }
}
impl Add for Point2D {
    type Output = Self;

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

impl Sub for Point2D {
    type Output = Self;

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

impl Mul for Point2D {
    type Output = Self;

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

impl Div for Point2D {
    type Output = Self;

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

impl From<[f64; 3]> for Point3D {
    fn from([x, y, z]: [f64; 3]) -> Self {
        Self { x, y, z }
    }
}

impl From<&[f64; 3]> for Point3D {
    fn from(p: &[f64; 3]) -> Self {
        let [x, y, z] = *p;
        Self { x, y, z }
    }
}

impl From<Point3D> for [f64; 3] {
    fn from(Point3D { x, y, z }: Point3D) -> Self {
        [x, y, z]
    }
}
impl Add for Point3D {
    type Output = Self;

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

impl Sub for Point3D {
    type Output = Self;

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

impl Mul for Point3D {
    type Output = Self;

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

impl Div for Point3D {
    type Output = Self;

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

impl Add<f64> for Point3D {
    type Output = Self;

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

impl Sub<f64> for Point3D {
    type Output = Self;

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

impl Mul<f64> for Point3D {
    type Output = Self;

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

impl Div<f64> for Point3D {
    type Output = Self;

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

impl Point3D {
    /// Add a Z component to a 2D point.
    pub fn with_z(Point2D { x, y }: Point2D, z: f64) -> Self {
        Self { x, y, z }
    }

    /// The origin
    pub const ZERO: Self = Self {
        x: 0.0,
        y: 0.0,
        z: 0.0,
    };
}

impl Point2D {
    /// The origin
    pub const ZERO: Self = Self { x: 0.0, y: 0.0 };
}

impl From<Point3D> for Point2D {
    fn from(Point3D { x, y, .. }: Point3D) -> Self {
        Point2D { x, y }
    }
}

#[cfg(test)]
mod tests {
    use std::f64::consts::PI;

    use super::*;

    #[test]
    fn scaling_points() {
        assert_eq!(Point2D { x: 1.0, y: 1.0 } * 3.0, Point2D { x: 3.0, y: 3.0 });
    }

    #[test]
    fn adding_points() {
        for (mut start, plus, expected) in [
            (
                Angle::ZERO,
                Angle::from_degrees(90.0),
                Angle::from_degrees(90.0),
            ),
            (
                Angle::from_radians(PI),
                Angle::from_degrees(180.0),
                Angle::from_radians(2.0 * PI),
            ),
            (
                Angle::from_radians(PI / 4.0),
                Angle::from_radians(PI / 4.0),
                Angle::from_radians(PI / 2.0),
            ),
        ] {
            assert_eq!((start + plus).degrees(), expected.degrees());
            start += plus;
            assert_eq!(start.degrees(), expected.degrees());
        }
    }
}