This commit is contained in:
Mahesh Asolkar 2024-08-14 20:11:37 -07:00
parent 3d885982cd
commit 914e3f2a0c

View File

@ -1,134 +0,0 @@
use std::str;
use std::fmt;
use curl::easy::{Easy, List};
use serde_json::Value;
//
// Enums
//
#[derive(Debug,PartialEq,Eq,Copy,Clone)]
enum TemperatureUnits {
Metric,
Imperial,
}
impl fmt::Display for TemperatureUnits {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
TemperatureUnits::Metric => write!(f, "Metric"),
TemperatureUnits::Imperial => write!(f, "Imperial"),
}
}
}
// Commandline parsing
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct CommandlineArgs {
/// Name of the weather station
#[arg(short, long, default_value = "khio")]
station: String,
}
//
// Application options
//
#[derive(Debug,Copy,Clone)]
struct AppOptions {
units: TemperatureUnits,
station: String,
}
//
// Application (BarWeather) actions
struct BarWeatherActions {
opts :AppOptions,
}
impl BarWeatherActions {
fn check_options(&self) -> bool {
let mut all_good = true;
if ! ((self.opts.units == TemperatureUnits::Metric)
|| (self.opts.units == TemperatureUnits::Imperial)) {
all_good &= false;
}
return all_good;
}
fn get_current_temperature(&self, v: Value) -> f32 {
let deg_c :f32 = v["features"][0]["properties"]["temperature"]["value"]
.to_string().parse().unwrap();
return if self.opts.units == TemperatureUnits::Metric { deg_c }
else { (deg_c * 9.0 / 5.0) + 32.0};
}
fn get_temperature_unit(&self) -> String{
return if self.opts.units == TemperatureUnits::Metric { "°C".to_string() }
else { "°F".to_string() };
}
}
//
// Application (BarWeather)
//
struct BarWeather {
acts :BarWeatherActions
}
impl BarWeather {
fn run(self) {
self.acts.check_options();
self.get_weather();
}
fn get_weather(self) {
// Print a web page onto stdout
let mut easy = Easy::new();
let app = self;
easy.url("https://api.weather.gov/stations/" + + "/observations?limit=1").unwrap();
let mut list = List::new();
list.append("User-Agent: Bar Weather (mahesh@heshapps.com)").unwrap();
easy.http_headers(list).unwrap();
easy.write_function(move |data| {
// To debug returned JSON
// use std::io::{stdout, Write};
// stdout().write_all(data).unwrap();
let v: Value = serde_json::from_str(str::from_utf8(data).unwrap()).unwrap();
let temperature_value :f32 = app.acts.get_current_temperature(v);
let temperature_unit :String = app.acts.get_temperature_unit();
println!("{}{}", temperature_value, temperature_unit);
println!("{:.2}{}", temperature_value, temperature_unit);
Ok(data.len())
}
).unwrap();
easy.perform().unwrap();
}
}
//
// Entry point
//
fn main() {
let app = BarWeather {
acts: BarWeatherActions {
opts: AppOptions {
units: TemperatureUnits::Imperial,
// units: TemperatureUnits::Metric,
},
},
};
app.run();
}
// References:
// https://reintech.io/blog/working-with-json-in-rust