newton 0.5.1

A Newtonian physics simulator written in Rust.
Documentation
// Newton - A Newtonian physics simulator written in Rust.
// Copyright (C) 2017 Cooper Paul EdenDay
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// Electronic mail: cedenday@protonmail.com

//! # Newton's Unit System
//! A simple unit system where you can safely convert to different units.
//! # Example
//! ```
//! use newton::units::{self, Eval};
//!
//! let speed = units::Velocity::new(5.0);
//! let time = units::Time::new(4.0);
//!
//! let distance = speed.displacement_time(time);
//! assert_eq!(distance.eval(), 20.0);
//! ```

#![allow(non_upper_case_globals)]
pub mod constants;

pub type Scalar = f64;

pub trait Eval {
    fn eval(&self) -> Scalar;
    fn new(value: Scalar) -> Self;
}

#[derive(Serialize, Deserialize, PartialEq, Debug, Copy, Clone)]
/// # Name
/// kilogram
/// # Definition
/// The kilogram is the unit of mass; it is equal to the mass of the
/// international prototype of the kilogram.
pub struct Mass {
    value: Scalar,
}
impl Eval for Mass {
    fn eval(&self) -> Scalar {
        self.value
    }
    fn new(value: Scalar) -> Self {
        Self { value: value }
    }
}

#[derive(Serialize, Deserialize, PartialEq, Debug, Copy, Clone)]
/// # Name
/// second
/// # Definition
/// The second is the duration of 9 192 631 770 periods of the radiation
/// corresponding to the transition between the two hyperfine levels of the
/// ground state of the caesium 133 atom.
/// Note: this definition refers to a caesium atom at rest at a temperature of 0 K.
pub struct Time {
    value: Scalar,
}
impl Eval for Time {
    fn eval(&self) -> Scalar {
        self.value
    }
    fn new(value: Scalar) -> Self {
        Self { value: value }
    }
}

#[derive(Serialize, Deserialize, PartialEq, Debug, Copy, Clone)]
/// # Name
/// metre
/// # Definition
/// The metre is the length of the path travelled by light in vacuum during a
/// time interval of 1/299 792 458 of a second.
pub struct Length {
    value: Scalar,
}
impl Eval for Length {
    fn eval(&self) -> Scalar {
        self.value
    }
    fn new(value: Scalar) -> Self {
        Self { value: value }
    }
}
impl Length {
    pub fn velocity_time(&self, time: Time) -> Velocity {
        Velocity { value: self.eval() / time.eval() }
    }
}

#[derive(Serialize, Deserialize, PartialEq, Debug, Copy, Clone)]
/// # Definition
/// m/s
pub struct Velocity {
    value: Scalar,
}
impl Eval for Velocity {
    fn eval(&self) -> Scalar {
        self.value
    }
    fn new(value: Scalar) -> Self {
        Self { value: value }
    }
}
impl Velocity {
    pub fn displacement_time(&self, time: Time) -> Length {
        Length { value: self.eval() * time.eval() }
    }
    pub fn acceleration_time(&self, time: Time) -> Acceleration {
        Acceleration { value: self.eval() / time.eval() }
    }
}

#[derive(Serialize, Deserialize, PartialEq, Debug, Copy, Clone)]
/// # Definition
/// m/s^2
pub struct Acceleration {
    value: Scalar,
}
impl Eval for Acceleration {
    fn eval(&self) -> Scalar {
        self.value
    }
    fn new(value: Scalar) -> Self {
        Self { value: value }
    }
}
impl Acceleration {
    pub fn velocity_time(&self, time: Time) -> Velocity {
        Velocity { value: self.eval() * time.eval() }
    }
}

#[derive(Serialize, Deserialize, PartialEq, Debug, Copy, Clone)]
/// # Name
/// newton
/// # Definition
/// kg·m/s^2
pub struct Force {
    value: Scalar,
}
impl Eval for Force {
    fn eval(&self) -> Scalar {
        self.value
    }
    fn new(value: Scalar) -> Self {
        Self { value: value }
    }
}
impl Force {
    pub fn acceleration_mass(&self, mass: Mass) -> Acceleration {
        Acceleration { value: self.eval() / mass.eval() }
    }
}