First commit
This commit is contained in:
140
src/main.rs
Normal file
140
src/main.rs
Normal file
@@ -0,0 +1,140 @@
|
||||
use std::str;
|
||||
use std::fmt;
|
||||
use curl::easy::{Easy, List};
|
||||
use serde_json::Value;
|
||||
use clap::Parser;
|
||||
|
||||
//
|
||||
// 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,
|
||||
|
||||
/// Use Metric units. Imperial units otherwise
|
||||
#[arg(short, long)]
|
||||
metric: bool,
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Application options
|
||||
//
|
||||
#[derive(Debug,Clone)]
|
||||
struct AppOptions {
|
||||
units: TemperatureUnits,
|
||||
station: String,
|
||||
}
|
||||
|
||||
//
|
||||
// Application (BarWeather)
|
||||
//
|
||||
struct BarWeather {
|
||||
// acts :BarWeatherActions
|
||||
opts :AppOptions,
|
||||
}
|
||||
|
||||
impl BarWeather {
|
||||
fn run(self) {
|
||||
self.check_options();
|
||||
self.get_weather();
|
||||
}
|
||||
|
||||
fn get_weather(self) {
|
||||
// Print a web page onto stdout
|
||||
let mut easy = Easy::new();
|
||||
let app = self;
|
||||
let url_string_1 :String = "https://api.weather.gov/stations/".to_owned();
|
||||
let url_string_2 :&str = app.opts.station.as_str();
|
||||
let url_string_3 :String = "/observations?limit=1".to_owned();
|
||||
let url_string = url_string_1 + url_string_2 + &url_string_3;
|
||||
easy.url(url_string.as_str()).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.get_current_temperature(v);
|
||||
let temperature_unit :String = app.get_temperature_unit();
|
||||
|
||||
println!("{}{}", temperature_value, temperature_unit);
|
||||
println!("{:.2}{}", temperature_value, temperature_unit);
|
||||
|
||||
Ok(data.len())
|
||||
|
||||
}
|
||||
).unwrap();
|
||||
easy.perform().unwrap();
|
||||
}
|
||||
|
||||
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() };
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Entry point
|
||||
//
|
||||
fn main() {
|
||||
let cmd_args = CommandlineArgs::parse();
|
||||
let app = BarWeather {
|
||||
//acts: BarWeatherActions {
|
||||
opts: AppOptions {
|
||||
// units: TemperatureUnits::Imperial,
|
||||
// units: TemperatureUnits::Metric,
|
||||
units: if cmd_args.metric { TemperatureUnits::Metric }
|
||||
else { TemperatureUnits::Imperial },
|
||||
station: cmd_args.station,
|
||||
},
|
||||
//},
|
||||
};
|
||||
|
||||
app.run();
|
||||
}
|
||||
// References:
|
||||
// https://reintech.io/blog/working-with-json-in-rust
|
134
src/main.rs.backup
Normal file
134
src/main.rs.backup
Normal file
@@ -0,0 +1,134 @@
|
||||
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
|
Reference in New Issue
Block a user