Skip to content

Commit d246ca5

Browse files
feat: add speed conversion module (#998)
1 parent 39607d1 commit d246ca5

File tree

3 files changed

+233
-0
lines changed

3 files changed

+233
-0
lines changed

DIRECTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
* [RGB-CMYK Conversion](https://github.com/TheAlgorithms/Rust/blob/master/src/conversions/rgb_cmyk_conversion.rs)
8787
* [RGB-HSV Conversion](https://github.com/TheAlgorithms/Rust/blob/master/src/conversions/rgb_hsv_conversion.rs)
8888
* [Roman Numerals](https://github.com/TheAlgorithms/Rust/blob/master/src/conversions/roman_numerals.rs)
89+
* [Speed](https://github.com/TheAlgorithms/Rust/blob/master/src/conversions/speed.rs)
8990
* [Time Units](https://github.com/TheAlgorithms/Rust/blob/master/src/conversions/time_units.rs)
9091
* Data Structures
9192
* [AVL Tree](https://github.com/TheAlgorithms/Rust/blob/master/src/data_structures/avl_tree.rs)

src/conversions/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ mod order_of_magnitude_conversion;
1616
mod rgb_cmyk_conversion;
1717
mod rgb_hsv_conversion;
1818
mod roman_numerals;
19+
mod speed;
1920
mod time_units;
2021

2122
pub use self::binary_to_decimal::binary_to_decimal;
@@ -38,4 +39,5 @@ pub use self::order_of_magnitude_conversion::{
3839
pub use self::rgb_cmyk_conversion::rgb_to_cmyk;
3940
pub use self::rgb_hsv_conversion::{hsv_to_rgb, rgb_to_hsv, ColorError, Hsv, Rgb};
4041
pub use self::roman_numerals::{int_to_roman, roman_to_int};
42+
pub use self::speed::{convert_speed, SpeedUnit};
4143
pub use self::time_units::convert_time;

src/conversions/speed.rs

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
//! Convert speed units
2+
//!
3+
//! References:
4+
//! - <https://en.wikipedia.org/wiki/Kilometres_per_hour>
5+
//! - <https://en.wikipedia.org/wiki/Miles_per_hour>
6+
//! - <https://en.wikipedia.org/wiki/Knot_(unit)>
7+
//! - <https://en.wikipedia.org/wiki/Metre_per_second>
8+
//! - <https://en.wikipedia.org/wiki/Foot_per_second>
9+
//! - <https://en.wikipedia.org/wiki/Mach_number>
10+
//! - <https://en.wikipedia.org/wiki/Speed_of_light>
11+
12+
use std::fmt;
13+
14+
/// Supported speed units
15+
#[derive(Debug, Clone, Copy, PartialEq)]
16+
pub enum SpeedUnit {
17+
/// Kilometers per hour (km/h)
18+
KilometersPerHour,
19+
/// Meters per second (m/s) - SI derived unit
20+
MetersPerSecond,
21+
/// Miles per hour (mph)
22+
MilesPerHour,
23+
/// Nautical miles per hour (knot)
24+
Knot,
25+
/// Feet per second (fps or ft/s)
26+
FeetPerSecond,
27+
/// Mach number (dimensionless) - speed divided by speed of sound at sea level (340.3 m/s)
28+
Mach,
29+
/// Speed of light (c) - speed divided by speed of light in vacuum (299,792,458 m/s)
30+
SpeedOfLight,
31+
}
32+
33+
impl fmt::Display for SpeedUnit {
34+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35+
match self {
36+
SpeedUnit::KilometersPerHour => write!(f, "km/h"),
37+
SpeedUnit::MetersPerSecond => write!(f, "m/s"),
38+
SpeedUnit::MilesPerHour => write!(f, "mph"),
39+
SpeedUnit::Knot => write!(f, "knot"),
40+
SpeedUnit::FeetPerSecond => write!(f, "ft/s"),
41+
SpeedUnit::Mach => write!(f, "Mach"),
42+
SpeedUnit::SpeedOfLight => write!(f, "c"),
43+
}
44+
}
45+
}
46+
47+
impl SpeedUnit {
48+
/// Get the conversion factor to km/h
49+
fn as_kmh_multiplier(self) -> f64 {
50+
match self {
51+
SpeedUnit::KilometersPerHour => 1.0,
52+
SpeedUnit::MetersPerSecond => 3.6,
53+
SpeedUnit::MilesPerHour => 1.609344,
54+
SpeedUnit::Knot => 1.852,
55+
SpeedUnit::FeetPerSecond => 1.09728,
56+
SpeedUnit::Mach => 1225.08,
57+
SpeedUnit::SpeedOfLight => 1_079_252_848.8,
58+
}
59+
}
60+
61+
/// Get the conversion factor from km/h to this unit
62+
fn kmh_multiplier(self) -> f64 {
63+
match self {
64+
SpeedUnit::KilometersPerHour => 1.0,
65+
SpeedUnit::MetersPerSecond => 0.277777778,
66+
SpeedUnit::MilesPerHour => 0.621371192,
67+
SpeedUnit::Knot => 0.539956803,
68+
SpeedUnit::FeetPerSecond => 0.911344415,
69+
SpeedUnit::Mach => 0.000816164,
70+
SpeedUnit::SpeedOfLight => 9.265669311e-10,
71+
}
72+
}
73+
}
74+
75+
/// Convert speed from one unit to another
76+
///
77+
/// # Arguments
78+
///
79+
/// * `speed` - The speed value to convert
80+
/// * `from` - The unit to convert from
81+
/// * `to` - The unit to convert to
82+
///
83+
/// # Returns
84+
///
85+
/// The converted speed value rounded to 3 decimal places
86+
pub fn convert_speed(speed: f64, from: SpeedUnit, to: SpeedUnit) -> f64 {
87+
let kmh = speed * from.as_kmh_multiplier();
88+
let result = kmh * to.kmh_multiplier();
89+
(result * 1000.0).round() / 1000.0
90+
}
91+
92+
#[cfg(test)]
93+
mod tests {
94+
use super::*;
95+
96+
#[test]
97+
fn test_speed_conversion() {
98+
assert_eq!(
99+
convert_speed(
100+
100.0,
101+
SpeedUnit::KilometersPerHour,
102+
SpeedUnit::MetersPerSecond
103+
),
104+
27.778
105+
);
106+
assert_eq!(
107+
convert_speed(100.0, SpeedUnit::KilometersPerHour, SpeedUnit::MilesPerHour),
108+
62.137
109+
);
110+
assert_eq!(
111+
convert_speed(100.0, SpeedUnit::KilometersPerHour, SpeedUnit::Knot),
112+
53.996
113+
);
114+
assert_eq!(
115+
convert_speed(
116+
100.0,
117+
SpeedUnit::MetersPerSecond,
118+
SpeedUnit::KilometersPerHour
119+
),
120+
360.0
121+
);
122+
assert_eq!(
123+
convert_speed(100.0, SpeedUnit::MetersPerSecond, SpeedUnit::MilesPerHour),
124+
223.694
125+
);
126+
assert_eq!(
127+
convert_speed(100.0, SpeedUnit::MetersPerSecond, SpeedUnit::Knot),
128+
194.384
129+
);
130+
assert_eq!(
131+
convert_speed(100.0, SpeedUnit::MilesPerHour, SpeedUnit::KilometersPerHour),
132+
160.934
133+
);
134+
assert_eq!(
135+
convert_speed(100.0, SpeedUnit::MilesPerHour, SpeedUnit::MetersPerSecond),
136+
44.704
137+
);
138+
assert_eq!(
139+
convert_speed(100.0, SpeedUnit::MilesPerHour, SpeedUnit::Knot),
140+
86.898
141+
);
142+
assert_eq!(
143+
convert_speed(100.0, SpeedUnit::Knot, SpeedUnit::KilometersPerHour),
144+
185.2
145+
);
146+
assert_eq!(
147+
convert_speed(100.0, SpeedUnit::Knot, SpeedUnit::MetersPerSecond),
148+
51.444
149+
);
150+
assert_eq!(
151+
convert_speed(100.0, SpeedUnit::Knot, SpeedUnit::MilesPerHour),
152+
115.078
153+
);
154+
assert_eq!(
155+
convert_speed(100.0, SpeedUnit::FeetPerSecond, SpeedUnit::MetersPerSecond),
156+
30.48
157+
);
158+
assert_eq!(
159+
convert_speed(100.0, SpeedUnit::MetersPerSecond, SpeedUnit::FeetPerSecond),
160+
328.084
161+
);
162+
assert_eq!(
163+
convert_speed(
164+
100.0,
165+
SpeedUnit::FeetPerSecond,
166+
SpeedUnit::KilometersPerHour
167+
),
168+
109.728
169+
);
170+
assert_eq!(
171+
convert_speed(100.0, SpeedUnit::FeetPerSecond, SpeedUnit::MilesPerHour),
172+
68.182
173+
);
174+
assert_eq!(
175+
convert_speed(1.0, SpeedUnit::Mach, SpeedUnit::KilometersPerHour),
176+
1225.08
177+
);
178+
assert_eq!(
179+
convert_speed(1.0, SpeedUnit::Mach, SpeedUnit::MetersPerSecond),
180+
340.3
181+
);
182+
assert_eq!(
183+
convert_speed(1000.0, SpeedUnit::KilometersPerHour, SpeedUnit::Mach),
184+
0.816
185+
);
186+
assert_eq!(
187+
convert_speed(2.0, SpeedUnit::Mach, SpeedUnit::KilometersPerHour),
188+
2450.16
189+
);
190+
assert_eq!(
191+
convert_speed(1.0, SpeedUnit::SpeedOfLight, SpeedUnit::MetersPerSecond),
192+
299792458.24
193+
);
194+
assert_eq!(
195+
convert_speed(1.0, SpeedUnit::SpeedOfLight, SpeedUnit::KilometersPerHour),
196+
1079252848.8
197+
);
198+
assert_eq!(
199+
convert_speed(
200+
299792458.0,
201+
SpeedUnit::MetersPerSecond,
202+
SpeedUnit::SpeedOfLight
203+
),
204+
1.0
205+
);
206+
assert_eq!(
207+
convert_speed(0.1, SpeedUnit::SpeedOfLight, SpeedUnit::MetersPerSecond),
208+
29979245.824
209+
);
210+
assert_eq!(
211+
convert_speed(
212+
100.0,
213+
SpeedUnit::KilometersPerHour,
214+
SpeedUnit::KilometersPerHour
215+
),
216+
100.0
217+
);
218+
}
219+
220+
#[test]
221+
fn test_display() {
222+
assert_eq!(SpeedUnit::KilometersPerHour.to_string(), "km/h");
223+
assert_eq!(SpeedUnit::MetersPerSecond.to_string(), "m/s");
224+
assert_eq!(SpeedUnit::MilesPerHour.to_string(), "mph");
225+
assert_eq!(SpeedUnit::Knot.to_string(), "knot");
226+
assert_eq!(SpeedUnit::FeetPerSecond.to_string(), "ft/s");
227+
assert_eq!(SpeedUnit::Mach.to_string(), "Mach");
228+
assert_eq!(SpeedUnit::SpeedOfLight.to_string(), "c");
229+
}
230+
}

0 commit comments

Comments
 (0)