Compare commits
4 Commits
a1270866a5
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
798c305a65 | ||
|
|
6947fdec04 | ||
|
|
a1add6d2f2 | ||
|
|
920c093ecf |
26
src/icons.rs
26
src/icons.rs
@@ -9,25 +9,29 @@ pub enum Icons {
|
||||
Snow,
|
||||
Clear,
|
||||
Cloudy,
|
||||
Thunderstorms,
|
||||
Fog,
|
||||
}
|
||||
|
||||
impl Icons {
|
||||
|
||||
pub fn get_icon_str(&self) -> String {
|
||||
pub fn icon_str(&self) -> String {
|
||||
match self {
|
||||
Icons::Fahrenheit => Self::get_icon("e341").unwrap().to_string(),
|
||||
Icons::Clock => Self::get_icon("e641").unwrap().to_string(),
|
||||
Icons::Baseball => Self::get_icon("f0852").unwrap().to_string(),
|
||||
Icons::Sunny => Self::get_icon("f0599").unwrap().to_string(),
|
||||
Icons::Mixed => Self::get_icon("f067f").unwrap().to_string(),
|
||||
Icons::Rain => Self::get_icon("e239").unwrap().to_string(),
|
||||
Icons::Snow => Self::get_icon("f0f36").unwrap().to_string(),
|
||||
Icons::Clear => Self::get_icon("e30d").unwrap().to_string(),
|
||||
Icons::Cloudy => Self::get_icon("e312").unwrap().to_string(),
|
||||
Icons::Fahrenheit => Self::icon("e341").unwrap().to_string(),
|
||||
Icons::Clock => Self::icon("e641").unwrap().to_string(),
|
||||
Icons::Baseball => Self::icon("f0852").unwrap().to_string(),
|
||||
Icons::Sunny => Self::icon("f0599").unwrap().to_string(),
|
||||
Icons::Mixed => Self::icon("f067f").unwrap().to_string(),
|
||||
Icons::Rain => Self::icon("e239").unwrap().to_string(),
|
||||
Icons::Snow => Self::icon("f0f36").unwrap().to_string(),
|
||||
Icons::Clear => Self::icon("e30d").unwrap().to_string(),
|
||||
Icons::Cloudy => Self::icon("e312").unwrap().to_string(),
|
||||
Icons::Thunderstorms => Self::icon("e338").unwrap().to_string(),
|
||||
Icons::Fog => Self::icon("e313").unwrap().to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_icon(code: &str) -> Option<char> {
|
||||
fn icon(code: &str) -> Option<char> {
|
||||
u32::from_str_radix(&code, 16).ok().and_then(char::from_u32)
|
||||
}
|
||||
}
|
||||
|
||||
28
src/main.rs
28
src/main.rs
@@ -1,5 +1,7 @@
|
||||
mod weather;
|
||||
mod redsox;
|
||||
use std::collections::HashMap;
|
||||
use redsox::GameInfo;
|
||||
mod icons;
|
||||
use icons::Icons;
|
||||
use tabled::{Table, Tabled};
|
||||
@@ -25,24 +27,34 @@ fn main() {
|
||||
y: 59,
|
||||
code: "GYX".to_string(),
|
||||
}.get_full_forecast();
|
||||
let sox_games: Vec<redsox::GameInfo> = redsox::get_schedule();
|
||||
let sox_games: HashMap<String,GameInfo> = redsox::get_schedule();
|
||||
// Build icons.
|
||||
let baseball_icon = Icons::Baseball.get_icon_str();
|
||||
let clock_icon = Icons::Clock.get_icon_str();
|
||||
let fahrenheit_icon = Icons::Fahrenheit.get_icon_str();
|
||||
let baseball_icon = Icons::Baseball.icon_str();
|
||||
let clock_icon = Icons::Clock.icon_str();
|
||||
let fahrenheit_icon = Icons::Fahrenheit.icon_str();
|
||||
// Build the rows for the table.
|
||||
let mut table_rows: Vec<TableRow> = vec![];
|
||||
let mut game_flag = false;
|
||||
for i in 0..entire_forecast.len() {
|
||||
let forecast_period = &entire_forecast[i];
|
||||
let yyyy_mm_dd = &forecast_period.start_time[0..10];
|
||||
let mut sox_status = String::new();
|
||||
// Check if there is a sox game and print opp.
|
||||
for sox_game in &sox_games {
|
||||
if sox_game.date == yyyy_mm_dd {
|
||||
sox_status = format!("{} {}\n{} {}", &baseball_icon, &sox_game.opponent, &clock_icon, &sox_game.start_time);
|
||||
break;
|
||||
if game_flag == false {
|
||||
if let Some(sox_game) = sox_games.get(yyyy_mm_dd) {
|
||||
sox_status = format!(
|
||||
"{} {}\n{} {}",
|
||||
&baseball_icon,
|
||||
&sox_game.opponent,
|
||||
&clock_icon,
|
||||
&sox_game.start_time
|
||||
);
|
||||
game_flag = true;
|
||||
}
|
||||
} else {
|
||||
game_flag = false;
|
||||
}
|
||||
|
||||
let row = TableRow {
|
||||
date: yyyy_mm_dd.to_string(),
|
||||
time_of_day: forecast_period.name.clone(),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_alias::serde_alias;
|
||||
use std::collections::HashMap;
|
||||
use chrono::{DateTime, Utc};
|
||||
use chrono_tz::US::Eastern;
|
||||
|
||||
@@ -63,26 +64,27 @@ pub struct GameInfo {
|
||||
pub start_time: String,
|
||||
}
|
||||
|
||||
// Gets the full forecast from the response.
|
||||
pub fn get_schedule() -> Vec<GameInfo> {
|
||||
// Gets the full schedule from the response.
|
||||
pub fn get_schedule() -> HashMap<String,GameInfo> {
|
||||
let client = reqwest::blocking::Client::new();
|
||||
let schedule_url = build_api_url();
|
||||
let schedule_json: String = client.get(&schedule_url).send().expect("Unable to get data").text().unwrap().to_string();
|
||||
let schedule: Schedule = serde_json::from_str(&schedule_json).expect("JSON was not well-formatted");
|
||||
let mut full_schedule: Vec<GameInfo> = vec![];
|
||||
let mut hashmap_schedule: HashMap<String,GameInfo> = HashMap::new();
|
||||
let dates = schedule.dates;
|
||||
for date in dates {
|
||||
for game in date.games {
|
||||
let facing = extract_opponent(&game.teams);
|
||||
let game_date: String = game.official_date.to_string();
|
||||
let game_info = GameInfo {
|
||||
opponent: facing,
|
||||
date: game.official_date,
|
||||
date: game_date,
|
||||
start_time: get_start_time(&game.game_date),
|
||||
};
|
||||
full_schedule.push(game_info);
|
||||
hashmap_schedule.insert(game.official_date, game_info);
|
||||
}
|
||||
}
|
||||
full_schedule
|
||||
hashmap_schedule
|
||||
}
|
||||
|
||||
// Determine who the opponent is from the teams.
|
||||
@@ -107,8 +109,6 @@ fn get_start_time(iso_string: &String) -> String {
|
||||
est_dt.format("%I:%M").to_string()
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod team_tests {
|
||||
use super::*;
|
||||
@@ -134,7 +134,6 @@ mod team_tests {
|
||||
fn test_get_start_time() {
|
||||
let iso_string = "2025-04-02T22:35:00Z".to_string(); // UTC time
|
||||
let result = get_start_time(&iso_string);
|
||||
|
||||
// EST is UTC-5 or UTC-4 depending on DST. April is typically daylight saving (EDT = UTC-4)
|
||||
assert_eq!(result, "06:35"); // 22:35 UTC == 18:35 EDT == 06:35 PM in 12-hour format
|
||||
}
|
||||
|
||||
@@ -73,14 +73,16 @@ impl WeatherOfficeLocation {
|
||||
// Detect which icon to display based on short forecast.
|
||||
pub fn detect_icon(short_forecast: &str) -> Option<String> {
|
||||
match true {
|
||||
_ if short_forecast.contains("Sunny") => Some(Icons::Sunny.get_icon_str()),
|
||||
_ if short_forecast.contains("Sunny") => Some(Icons::Sunny.icon_str()),
|
||||
_ if short_forecast.contains("Rain") && short_forecast.contains("Snow") => {
|
||||
Some(Icons::Mixed.get_icon_str())
|
||||
Some(Icons::Mixed.icon_str())
|
||||
}
|
||||
_ if short_forecast.contains("Snow") => Some(Icons::Snow.get_icon_str()),
|
||||
_ if short_forecast.contains("Rain") => Some(Icons::Rain.get_icon_str()),
|
||||
_ if short_forecast.contains("Cloudy") => Some(Icons::Cloudy.get_icon_str()),
|
||||
_ if short_forecast.contains("Clear") => Some(Icons::Clear.get_icon_str()),
|
||||
_ if short_forecast.contains("Thunderstorms") => Some(Icons::Thunderstorms.icon_str()),
|
||||
_ if short_forecast.contains("Snow") => Some(Icons::Snow.icon_str()),
|
||||
_ if short_forecast.contains("Rain") => Some(Icons::Rain.icon_str()),
|
||||
_ if short_forecast.contains("Cloudy") => Some(Icons::Cloudy.icon_str()),
|
||||
_ if short_forecast.contains("Clear") => Some(Icons::Clear.icon_str()),
|
||||
_ if short_forecast.contains("Fog") => Some(Icons::Fog.icon_str()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user