Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
* [RGB-CMYK Conversion](https://github.com/TheAlgorithms/Rust/blob/master/src/conversions/rgb_cmyk_conversion.rs)
* [RGB-HSV Conversion](https://github.com/TheAlgorithms/Rust/blob/master/src/conversions/rgb_hsv_conversion.rs)
* [Roman Numerals](https://github.com/TheAlgorithms/Rust/blob/master/src/conversions/roman_numerals.rs)
* [Speed](https://github.com/TheAlgorithms/Rust/blob/master/src/conversions/speed.rs)
* [Time Units](https://github.com/TheAlgorithms/Rust/blob/master/src/conversions/time_units.rs)
* Data Structures
* [AVL Tree](https://github.com/TheAlgorithms/Rust/blob/master/src/data_structures/avl_tree.rs)
Expand Down
2 changes: 2 additions & 0 deletions src/conversions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ mod order_of_magnitude_conversion;
mod rgb_cmyk_conversion;
mod rgb_hsv_conversion;
mod roman_numerals;
mod speed;
mod time_units;

pub use self::binary_to_decimal::binary_to_decimal;
Expand All @@ -38,4 +39,5 @@ pub use self::order_of_magnitude_conversion::{
pub use self::rgb_cmyk_conversion::rgb_to_cmyk;
pub use self::rgb_hsv_conversion::{hsv_to_rgb, rgb_to_hsv, ColorError, Hsv, Rgb};
pub use self::roman_numerals::{int_to_roman, roman_to_int};
pub use self::speed::{convert_speed, SpeedUnit};
pub use self::time_units::convert_time;
230 changes: 230 additions & 0 deletions src/conversions/speed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
//! Convert speed units
//!
//! References:
//! - <https://en.wikipedia.org/wiki/Kilometres_per_hour>
//! - <https://en.wikipedia.org/wiki/Miles_per_hour>
//! - <https://en.wikipedia.org/wiki/Knot_(unit)>
//! - <https://en.wikipedia.org/wiki/Metre_per_second>
//! - <https://en.wikipedia.org/wiki/Foot_per_second>
//! - <https://en.wikipedia.org/wiki/Mach_number>
//! - <https://en.wikipedia.org/wiki/Speed_of_light>

use std::fmt;

/// Supported speed units
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum SpeedUnit {
/// Kilometers per hour (km/h)
KilometersPerHour,
/// Meters per second (m/s) - SI derived unit
MetersPerSecond,
/// Miles per hour (mph)
MilesPerHour,
/// Nautical miles per hour (knot)
Knot,
/// Feet per second (fps or ft/s)
FeetPerSecond,
/// Mach number (dimensionless) - speed divided by speed of sound at sea level (340.3 m/s)
Mach,
/// Speed of light (c) - speed divided by speed of light in vacuum (299,792,458 m/s)
SpeedOfLight,
}

impl fmt::Display for SpeedUnit {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SpeedUnit::KilometersPerHour => write!(f, "km/h"),
SpeedUnit::MetersPerSecond => write!(f, "m/s"),
SpeedUnit::MilesPerHour => write!(f, "mph"),
SpeedUnit::Knot => write!(f, "knot"),
SpeedUnit::FeetPerSecond => write!(f, "ft/s"),
SpeedUnit::Mach => write!(f, "Mach"),
SpeedUnit::SpeedOfLight => write!(f, "c"),
}
}
}

impl SpeedUnit {
/// Get the conversion factor to km/h
fn as_kmh_multiplier(self) -> f64 {
match self {
SpeedUnit::KilometersPerHour => 1.0,
SpeedUnit::MetersPerSecond => 3.6,
SpeedUnit::MilesPerHour => 1.609344,
SpeedUnit::Knot => 1.852,
SpeedUnit::FeetPerSecond => 1.09728,
SpeedUnit::Mach => 1225.08,
SpeedUnit::SpeedOfLight => 1_079_252_848.8,
}
}

/// Get the conversion factor from km/h to this unit
fn kmh_multiplier(self) -> f64 {
match self {
SpeedUnit::KilometersPerHour => 1.0,
SpeedUnit::MetersPerSecond => 0.277777778,
SpeedUnit::MilesPerHour => 0.621371192,
SpeedUnit::Knot => 0.539956803,
SpeedUnit::FeetPerSecond => 0.911344415,
SpeedUnit::Mach => 0.000816164,
SpeedUnit::SpeedOfLight => 9.265669311e-10,
}
}
}

/// Convert speed from one unit to another
///
/// # Arguments
///
/// * `speed` - The speed value to convert
/// * `from` - The unit to convert from
/// * `to` - The unit to convert to
///
/// # Returns
///
/// The converted speed value rounded to 3 decimal places
pub fn convert_speed(speed: f64, from: SpeedUnit, to: SpeedUnit) -> f64 {
let kmh = speed * from.as_kmh_multiplier();
let result = kmh * to.kmh_multiplier();
(result * 1000.0).round() / 1000.0
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_speed_conversion() {
assert_eq!(
convert_speed(
100.0,
SpeedUnit::KilometersPerHour,
SpeedUnit::MetersPerSecond
),
27.778
);
assert_eq!(
convert_speed(100.0, SpeedUnit::KilometersPerHour, SpeedUnit::MilesPerHour),
62.137
);
assert_eq!(
convert_speed(100.0, SpeedUnit::KilometersPerHour, SpeedUnit::Knot),
53.996
);
assert_eq!(
convert_speed(
100.0,
SpeedUnit::MetersPerSecond,
SpeedUnit::KilometersPerHour
),
360.0
);
assert_eq!(
convert_speed(100.0, SpeedUnit::MetersPerSecond, SpeedUnit::MilesPerHour),
223.694
);
assert_eq!(
convert_speed(100.0, SpeedUnit::MetersPerSecond, SpeedUnit::Knot),
194.384
);
assert_eq!(
convert_speed(100.0, SpeedUnit::MilesPerHour, SpeedUnit::KilometersPerHour),
160.934
);
assert_eq!(
convert_speed(100.0, SpeedUnit::MilesPerHour, SpeedUnit::MetersPerSecond),
44.704
);
assert_eq!(
convert_speed(100.0, SpeedUnit::MilesPerHour, SpeedUnit::Knot),
86.898
);
assert_eq!(
convert_speed(100.0, SpeedUnit::Knot, SpeedUnit::KilometersPerHour),
185.2
);
assert_eq!(
convert_speed(100.0, SpeedUnit::Knot, SpeedUnit::MetersPerSecond),
51.444
);
assert_eq!(
convert_speed(100.0, SpeedUnit::Knot, SpeedUnit::MilesPerHour),
115.078
);
assert_eq!(
convert_speed(100.0, SpeedUnit::FeetPerSecond, SpeedUnit::MetersPerSecond),
30.48
);
assert_eq!(
convert_speed(100.0, SpeedUnit::MetersPerSecond, SpeedUnit::FeetPerSecond),
328.084
);
assert_eq!(
convert_speed(
100.0,
SpeedUnit::FeetPerSecond,
SpeedUnit::KilometersPerHour
),
109.728
);
assert_eq!(
convert_speed(100.0, SpeedUnit::FeetPerSecond, SpeedUnit::MilesPerHour),
68.182
);
assert_eq!(
convert_speed(1.0, SpeedUnit::Mach, SpeedUnit::KilometersPerHour),
1225.08
);
assert_eq!(
convert_speed(1.0, SpeedUnit::Mach, SpeedUnit::MetersPerSecond),
340.3
);
assert_eq!(
convert_speed(1000.0, SpeedUnit::KilometersPerHour, SpeedUnit::Mach),
0.816
);
assert_eq!(
convert_speed(2.0, SpeedUnit::Mach, SpeedUnit::KilometersPerHour),
2450.16
);
assert_eq!(
convert_speed(1.0, SpeedUnit::SpeedOfLight, SpeedUnit::MetersPerSecond),
299792458.24
);
assert_eq!(
convert_speed(1.0, SpeedUnit::SpeedOfLight, SpeedUnit::KilometersPerHour),
1079252848.8
);
assert_eq!(
convert_speed(
299792458.0,
SpeedUnit::MetersPerSecond,
SpeedUnit::SpeedOfLight
),
1.0
);
assert_eq!(
convert_speed(0.1, SpeedUnit::SpeedOfLight, SpeedUnit::MetersPerSecond),
29979245.824
);
assert_eq!(
convert_speed(
100.0,
SpeedUnit::KilometersPerHour,
SpeedUnit::KilometersPerHour
),
100.0
);
}

#[test]
fn test_display() {
assert_eq!(SpeedUnit::KilometersPerHour.to_string(), "km/h");
assert_eq!(SpeedUnit::MetersPerSecond.to_string(), "m/s");
assert_eq!(SpeedUnit::MilesPerHour.to_string(), "mph");
assert_eq!(SpeedUnit::Knot.to_string(), "knot");
assert_eq!(SpeedUnit::FeetPerSecond.to_string(), "ft/s");
assert_eq!(SpeedUnit::Mach.to_string(), "Mach");
assert_eq!(SpeedUnit::SpeedOfLight.to_string(), "c");
}
}