use std::fmt;
use std::io;
use Temperature::*;
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum Temperature {
Kelvin(f64),
Celsius(f64),
Fahrenheit(f64),
Rankine(f64),
}
impl fmt::Display for Temperature {
fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result {
match *self {
Kelvin(k) => write!(fmtr, "{}K", k),
Celsius(c) => write!(fmtr, "{}°C", c),
Fahrenheit(f) => write!(fmtr, "{}°F", f),
Rankine(r) => write!(fmtr, "{}°R", r),
}
}
}
impl Temperature {
pub fn to_celsius(self) -> Temperature {
match self {
Kelvin(k) => Celsius(k - 273.15),
c @ Celsius(_) => c,
Fahrenheit(f) => Celsius((f - 32.0) * (5.0 / 9.0)),
Rankine(r) => Celsius((r - 491.67) * 5.0 / 9.0),
}
}
pub fn to_fahrenheit(self) -> Temperature {
match self {
Kelvin(k) => Fahrenheit((k * (9.0 / 5.0)) - 459.67),
Celsius(c) => Fahrenheit((c * (9.0 / 5.0)) + 32.0),
f @ Fahrenheit(_) => f,
Rankine(r) => Fahrenheit(r - 459.67),
}
}
pub fn to_kelvin(self) -> Temperature {
match self {
k @ Kelvin(_) => k,
Celsius(c) => Kelvin(c + 273.15),
Fahrenheit(f) => Kelvin((f + 459.67) * (5.0 / 9.0)),
Rankine(r) => Kelvin(r * 5.0 / 9.0),
}
}
pub fn to_rankine(self) -> Temperature {
match self {
r @ Rankine(_) => r,
Celsius(c) => Rankine((c + 273.15) * 9.0 / 5.0),
Fahrenheit(f) => Rankine(f + 459.67),
Kelvin(k) => Rankine(k * 9.0 / 5.0),
}
}
}
pub fn convert_temp(temperature: &Temperature) -> f64 {
match *temperature {
Fahrenheit(degrees) => {
(degrees - 32.0) / 1.8
},
Fahrenheit(degrees) => {
((degrees - 32.0) / 1.8) + 273.15
},
Fahrenheit(degrees) => {
degrees + 456.67
},
Celsius(degrees) => {
(degrees * 1.8) + 32.0
},
Celsius(degrees) => {
degrees + 273.15
},
Celsius(degrees) => {
(degrees + 273.15) * 9.0 / 5.0
},
Kelvin(degrees) => {
degrees - 273.15
},
Kelvin(degrees) => {
((degrees - 273.15) * 1.8) + 32.0
},
Kelvin(degrees) => {
degrees * 9.0 / 5.0
},
Rankine(degrees) => {
(degrees - 491.67) * 5.0 / 9.0
},
Rankine(degrees) => {
degrees * 9.0 / 5.0 - 459.67
},
Rankine(degrees) => {
degrees * 5.0 / 9.0
},
}
}
pub fn print_temp(temperature: &Temperature) {
match *temperature {
Fahrenheit(degrees) => {
println!("{}F = {}C", degrees, convert_temp(temperature))
}
Fahrenheit(degrees) => {
println!("{}F = {}K", degrees, convert_temp(temperature))
}
Fahrenheit(degrees) => {
println!("{}F = {}R", degrees, convert_temp(temperature))
}
Celsius(degrees) => {
println!("{}C = {}F", degrees, convert_temp(temperature))
},
Celsius(degrees) => {
println!("{}C = {}K", degrees, convert_temp(temperature))
},
Celsius(degrees) => {
println!("{}C = {}R", degrees, convert_temp(temperature))
},
Kelvin(degrees) => {
println!("{}K = {}C", degrees, convert_temp(temperature))
},
Kelvin(degrees) => {
println!("{}K = {}F", degrees, convert_temp(temperature))
},
Kelvin(degrees) => {
println!("{}K = {}R", degrees, convert_temp(temperature))
},
Rankine(degrees) => {
println!("{}R = {}C", degrees, convert_temp(temperature))
},
Rankine(degrees) => {
println!("{}R = {}F", degrees, convert_temp(temperature))
},
Rankine(degrees) => {
println!("{}R = {}K", degrees, convert_temp(temperature))
},
}
}
pub fn get_user_temp() {
println!("\nType \"exit\" to exit the program");
loop {
let mut temp_input = String::new();
println!(
"\nPlease input a temperature you want to convert (Example: 10R, 10F, 10K, or \
-10C):"
);
io::stdin()
.read_line(&mut temp_input)
.expect("Failed to read line");
let trimmed = temp_input.trim();
if trimmed == "exit" {
break;
}
let (temp, scale) = trimmed.split_at(trimmed.len() - 1);
let temp: f64 = match temp.parse() {
Ok(num) => num,
Err(_) => continue,
};
let temp: Temperature = match scale {
"C" => Celsius(temp),
"F" => Fahrenheit(temp),
"K" => Kelvin(temp),
"R" => Rankine(temp),
_ => continue,
};
print_temp(&temp);
}
}
fn main() {
println!("This is a temperature converter!\n");
get_user_temp();
}