Skip to content

Commit 93d8ad3

Browse files
author
James O'Cull
committed
Basic lengths module. Has tests! Terrible organization and dead code warnings everywhere.
0 parents  commit 93d8ad3

File tree

4 files changed

+271
-0
lines changed

4 files changed

+271
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
target
2+
Cargo.lock

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[package]
2+
name = "measurements"
3+
version = "0.1.0"
4+
authors = ["James O'Cull <[email protected]>"]

src/lib.rs

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
mod tests;
2+
3+
use std::ops::{Add,Sub,Div,Mul};
4+
5+
#[derive(Copy, Clone, Debug)]
6+
pub struct Length {
7+
meters: f64
8+
}
9+
10+
// Constants, metric
11+
const METER_NANOMETER_FACTOR: f64 = 1000000000.0;
12+
const METER_MICROMETER_FACTOR: f64 = 1000000.0;
13+
const METER_MILLIMETER_FACTOR: f64 = 1000.0;
14+
const METER_CENTIMETER_FACTOR: f64 = 100.0;
15+
const METER_DECAMETER_FACTOR: f64 = 0.1;
16+
const METER_HECTOMETER_FACTOR: f64 = 0.01;
17+
const METER_KILOMETER_FACTOR: f64 = 0.001;
18+
19+
// Constants, imperial
20+
const METER_INCH_FACTOR: f64 = 39.3700787402;
21+
const METER_FEET_FACTOR: f64 = 3.28083989501;
22+
const METER_YARD_FACTOR: f64 = 1.09361329834;
23+
const METER_FURLONG_FACTOR: f64 = 0.0049709695379;
24+
const METER_MILE_FACTOR: f64 = 0.000621371192237;
25+
26+
impl Length {
27+
// Inputs, metric
28+
pub fn from_meters(meters: f64) -> Length {
29+
Length { meters: meters }
30+
}
31+
32+
fn from_nanometers(nanometers: f64) -> Length {
33+
Self::from_meters(nanometers / METER_NANOMETER_FACTOR)
34+
}
35+
36+
fn from_micrometers(micrometers: f64) -> Length {
37+
Self::from_meters(micrometers / METER_MICROMETER_FACTOR)
38+
}
39+
40+
fn from_millimeters(millimeters: f64) -> Length {
41+
Self::from_meters(millimeters / METER_MILLIMETER_FACTOR)
42+
}
43+
44+
fn from_centimeters(centimeters: f64) -> Length {
45+
Self::from_meters(centimeters / METER_CENTIMETER_FACTOR)
46+
}
47+
48+
fn from_decameters(decameters: f64) -> Length {
49+
Self::from_meters(decameters / METER_DECAMETER_FACTOR)
50+
}
51+
52+
fn from_hectometers(hectometers: f64) -> Length {
53+
Self::from_meters(hectometers / METER_HECTOMETER_FACTOR)
54+
}
55+
56+
fn from_kilometers(kilometers: f64) -> Length {
57+
Self::from_meters(kilometers / METER_KILOMETER_FACTOR)
58+
}
59+
60+
// Inputs, imperial
61+
fn from_inches(inches: f64) -> Length {
62+
Self::from_meters(inches / METER_INCH_FACTOR)
63+
}
64+
65+
fn from_feet(feet: f64) -> Length {
66+
Self::from_meters(feet / METER_FEET_FACTOR)
67+
}
68+
69+
fn from_yards(yards: f64) -> Length {
70+
Self::from_meters(yards / METER_YARD_FACTOR)
71+
}
72+
73+
fn from_furlongs(furlongs: f64) -> Length {
74+
Self::from_meters(furlongs / METER_FURLONG_FACTOR)
75+
}
76+
77+
fn from_miles(miles: f64) -> Length {
78+
Self::from_meters(miles / METER_MILE_FACTOR)
79+
}
80+
81+
// Outputs, metric
82+
fn as_nanometers(&self) -> f64 {
83+
self.meters * METER_NANOMETER_FACTOR
84+
}
85+
86+
fn as_micrometers(&self) -> f64 {
87+
self.meters * METER_MICROMETER_FACTOR
88+
}
89+
90+
fn as_millimeters(&self) -> f64 {
91+
self.meters * METER_MILLIMETER_FACTOR
92+
}
93+
94+
fn as_centimeters(&self) -> f64 {
95+
self.meters * METER_CENTIMETER_FACTOR
96+
}
97+
98+
fn as_meters(&self) -> f64 {
99+
self.meters
100+
}
101+
102+
fn as_decameters(&self) -> f64 {
103+
self.meters * METER_DECAMETER_FACTOR
104+
}
105+
106+
fn as_hectometer(&self) -> f64 {
107+
self.meters * METER_HECTOMETER_FACTOR
108+
}
109+
110+
fn as_kilometers(&self) -> f64 {
111+
self.meters * METER_KILOMETER_FACTOR
112+
}
113+
114+
// Outputs, imperial
115+
fn as_inches(&self) -> f64 {
116+
self.meters * METER_INCH_FACTOR
117+
}
118+
119+
fn as_feet(&self) -> f64 {
120+
self.meters * METER_FEET_FACTOR
121+
}
122+
123+
fn as_yards(&self) -> f64 {
124+
self.meters * METER_YARD_FACTOR
125+
}
126+
127+
fn as_furlongs(&self) -> f64 {
128+
self.meters * METER_FURLONG_FACTOR
129+
}
130+
131+
fn as_miles(&self) -> f64 {
132+
self.meters * METER_MILE_FACTOR
133+
}
134+
}
135+
136+
impl Add for Length {
137+
type Output = Length;
138+
139+
fn add(self, rhs: Length) -> Length {
140+
Length::from_meters(self.meters + rhs.meters)
141+
}
142+
}
143+
144+
impl Sub for Length {
145+
type Output = Length;
146+
147+
fn sub(self, rhs: Length) -> Length {
148+
Length::from_meters(self.meters - rhs.meters)
149+
}
150+
}
151+
152+
impl Div for Length {
153+
type Output = Length;
154+
155+
fn div(self, rhs: Length) -> Length {
156+
Length::from_meters(self.meters / rhs.meters)
157+
}
158+
}
159+
160+
impl Mul for Length {
161+
type Output = Length;
162+
163+
fn mul(self, rhs: Length) -> Length {
164+
Length::from_meters(self.meters * rhs.meters)
165+
}
166+
}

src/tests.rs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
const DEFAULT_DELTA: f64 = 0.000001;
2+
3+
use super::Length;
4+
5+
fn almost_eq(a: f64, b: f64) -> bool {
6+
almost_eq_delta(a, b, DEFAULT_DELTA)
7+
}
8+
9+
fn almost_eq_delta(a: f64, b: f64, d: f64) -> bool {
10+
(a - b).abs() < d
11+
}
12+
13+
fn assert_almost_eq(a: f64, b: f64) {
14+
assert_almost_eq_delta(a, b, DEFAULT_DELTA);
15+
}
16+
17+
fn assert_almost_eq_delta(a: f64, b: f64, d: f64) {
18+
if !almost_eq_delta(a, b, d) {
19+
panic!("assertion failed: {:?} != {:?} (within {:?})", a, b, d);
20+
}
21+
}
22+
23+
#[test]
24+
fn nanometers() {
25+
// Basic tests
26+
assert_almost_eq(Length::from_meters(1.0).as_nanometers(), super::METER_NANOMETER_FACTOR);
27+
assert_almost_eq(Length::from_nanometers(super::METER_NANOMETER_FACTOR).as_meters(), 1.0);
28+
29+
// Floating-point precision tests
30+
assert_almost_eq(Length::from_nanometers(1.0).as_nanometers(), Length::from_nanometers(1.0).as_nanometers());
31+
assert_almost_eq(Length::from_nanometers(0.00025).as_nanometers(), Length::from_nanometers(0.00025).as_nanometers());
32+
}
33+
34+
#[test]
35+
fn micrometers() {
36+
assert_almost_eq(Length::from_meters(1.0).as_micrometers(), super::METER_MICROMETER_FACTOR);
37+
assert_almost_eq(Length::from_micrometers(super::METER_MICROMETER_FACTOR).as_meters(), 1.0);
38+
}
39+
40+
#[test]
41+
fn millimeters() {
42+
assert_almost_eq(Length::from_meters(1.0).as_millimeters(), super::METER_MILLIMETER_FACTOR);
43+
assert_almost_eq(Length::from_millimeters(super::METER_MILLIMETER_FACTOR).as_meters(), 1.0);
44+
}
45+
46+
#[test]
47+
fn centimeters() {
48+
assert_almost_eq(Length::from_meters(1.0).as_centimeters(), super::METER_CENTIMETER_FACTOR);
49+
assert_almost_eq(Length::from_centimeters(super::METER_CENTIMETER_FACTOR).as_meters(), 1.0);
50+
}
51+
52+
#[test]
53+
fn decameter() {
54+
assert_almost_eq(Length::from_meters(1.0).as_decameters(), super::METER_DECAMETER_FACTOR);
55+
assert_almost_eq(Length::from_decameters(super::METER_DECAMETER_FACTOR).as_meters(), 1.0);
56+
}
57+
58+
#[test]
59+
fn hectometer() {
60+
assert_almost_eq(Length::from_meters(1.0).as_hectometer(), super::METER_HECTOMETER_FACTOR);
61+
assert_almost_eq(Length::from_hectometers(super::METER_HECTOMETER_FACTOR).as_meters(), 1.0);
62+
}
63+
64+
#[test]
65+
fn kilometer() {
66+
assert_almost_eq(Length::from_meters(1.0).as_kilometers(), super::METER_KILOMETER_FACTOR);
67+
assert_almost_eq(Length::from_kilometers(super::METER_KILOMETER_FACTOR).as_meters(), 1.0);
68+
}
69+
70+
// Imperial
71+
#[test]
72+
fn inches() {
73+
assert_almost_eq(Length::from_meters(1.0).as_inches(), super::METER_INCH_FACTOR);
74+
assert_almost_eq(Length::from_inches(super::METER_INCH_FACTOR).as_meters(), 1.0);
75+
}
76+
77+
#[test]
78+
fn feet() {
79+
assert_almost_eq(Length::from_meters(1.0).as_feet(), super::METER_FEET_FACTOR);
80+
assert_almost_eq(Length::from_feet(super::METER_FEET_FACTOR).as_meters(), 1.0);
81+
}
82+
83+
#[test]
84+
fn yards() {
85+
assert_almost_eq(Length::from_meters(1.0).as_yards(), super::METER_YARD_FACTOR);
86+
assert_almost_eq(Length::from_yards(super::METER_YARD_FACTOR).as_meters(), 1.0);
87+
}
88+
89+
#[test]
90+
fn furlongs() {
91+
assert_almost_eq(Length::from_meters(201.168).as_furlongs(), 1.0);
92+
assert_almost_eq(Length::from_furlongs(1.0).as_meters(), 201.168);
93+
}
94+
95+
#[test]
96+
fn miles() {
97+
assert_almost_eq(Length::from_meters(1609.344).as_miles(), 1.0);
98+
assert_almost_eq(Length::from_miles(1.0).as_meters(), 1609.344);
99+
}

0 commit comments

Comments
 (0)