diff --git a/src/github_api.rs b/src/github_api.rs index a824c5a..2898371 100644 --- a/src/github_api.rs +++ b/src/github_api.rs @@ -2,9 +2,14 @@ use anyhow::Result; use colored::*; use serde::Deserialize; +enum IncidentType { + ALL, + UNRESOLVED, +} + #[derive(Deserialize, Debug)] pub struct Component { - pub created_at: String, + pub created_at: Option, pub description: Option, pub id: String, pub name: String, @@ -16,10 +21,10 @@ pub struct Component { #[derive(Deserialize, Debug)] pub struct Incident { - pub create_at: String, + pub created_at: Option, pub id: String, pub impact: String, - pub incedent_updates: Vec, + pub incedent_updates: Option>, pub monitoring_at: Option, pub name: String, pub page_id: String, @@ -32,8 +37,8 @@ pub struct Incident { #[derive(Deserialize, Debug)] pub struct IncidentUpdate { pub body: String, - pub created_at: String, - pub display_at: String, + pub created_at: Option, + pub display_at: Option, pub id: String, pub incident_id: String, pub status: String, @@ -50,7 +55,7 @@ pub struct Page { #[derive(Deserialize, Debug)] pub struct ScheduledMaintenance { - pub created_at: String, + pub created_at: Option, pub id: String, pub impact: String, pub incident_updates: Vec, @@ -78,38 +83,48 @@ pub struct ComponentInfo { } impl ComponentInfo { - pub fn print() -> Result<()> { - let status = get_component_status()?; - - for component in status.components { - if component.description.is_some() { - if component.status == "operational" { - println!("{}: {}", component.name, component.status.green()); - } else if component.status == "degraded_performance" { - println!("{}: {}", component.name, component.status.yellow()); - } else if component.status == "partial_outge" { - println!( - "{}: {}", - component.name, - component.status.truecolor(255, 165, 0) - ); - } else if component.status == "major_outage" { - println!("{}: {}", component.name, component.status.red()); - } else { - println!("{}: {}", component.name, component.status); - } + fn get_component_status() -> Result { + let result = reqwest::blocking::get("https://www.githubstatus.com/api/v2/components.json")? + .json::()?; - if let Some(updated_at) = component.updated_at { - println!(" Last Updated At: {}", updated_at); + Ok(result) + } + + pub fn print() { + let status = ComponentInfo::get_component_status(); + + match status { + Ok(s) => { + for component in s.components { + if component.description.is_some() { + if component.status == "operational" { + println!("{}: {}", component.name, component.status.green()); + } else if component.status == "degraded_performance" { + println!("{}: {}", component.name, component.status.yellow()); + } else if component.status == "partial_outge" { + println!( + "{}: {}", + component.name, + component.status.truecolor(255, 165, 0) + ); + } else if component.status == "major_outage" { + println!("{}: {}", component.name, component.status.red()); + } else { + println!("{}: {}", component.name, component.status); + } + + if let Some(updated_at) = component.updated_at { + println!(" Last Updated At: {}", updated_at); + } + + println!(); + } } - println!(); + println!("More info: {:?}", s.page.url); } - } - - println!("More info: {:?}", status.page.url); - - Ok(()) + _ => println!("{}", "Error retrieving information".red()), + }; } } @@ -120,28 +135,38 @@ pub struct StatusInfo { } impl StatusInfo { - pub fn print() -> Result<()> { - let status = get_status()?; - - if status.status.indicator == "none" { - println!("{}", status.status.description.green()); - } else if status.status.indicator == "minor" { - println!("{}", status.status.description.yellow()); - } else if status.status.indicator == "major" { - println!("{}", status.status.description.truecolor(255, 165, 0)); - } else if status.status.indicator == "critical" { - println!("{}", status.status.description.red()); - } else { - println!("{}", status.status.description); - } + fn get_status() -> Result { + let result = reqwest::blocking::get("https://www.githubstatus.com/api/v2/status.json")? + .json::()?; - println!(); - if let Some(updated_at) = status.page.updated_at { - println!("Last update: {}", updated_at); - } - println!("More info: {}", status.page.url); + Ok(result) + } - Ok(()) + pub fn print() { + let status = StatusInfo::get_status(); + + match status { + Ok(s) => { + if s.status.indicator == "none" { + println!("{}", s.status.description.green()); + } else if s.status.indicator == "minor" { + println!("{}", s.status.description.yellow()); + } else if s.status.indicator == "major" { + println!("{}", s.status.description.truecolor(255, 165, 0)); + } else if s.status.indicator == "critical" { + println!("{}", s.status.description.red()); + } else { + println!("{}", s.status.description); + } + + println!(); + if let Some(updated_at) = s.page.updated_at { + println!("Last update: {}", updated_at); + } + println!("More info: {}", s.page.url); + } + _ => println!("{}", "Error retrieving information".red()), + }; } } @@ -155,66 +180,95 @@ pub struct SummaryInfo { } impl SummaryInfo { - pub fn print() -> Result<()> { - let summary = get_summary()?; - if summary.status.indicator == "none" { - println!("{}", summary.status.description.green()); - } else if summary.status.indicator == "minor" { - println!("{}", summary.status.description.yellow()); - } else if summary.status.indicator == "major" { - println!("{}", summary.status.description.truecolor(255, 165, 0)); - } else if summary.status.indicator == "critical" { - println!("{}", summary.status.description.red()); - } else { - println!("{}", summary.status.description); - } + fn get_summary() -> Result { + let result = reqwest::blocking::get("https://www.githubstatus.com/api/v2/summary.json")? + .json::()?; - println!(); - - for component in summary.components { - if component.description.is_some() { - if component.status == "operational" { - println!("{}: {}", component.name, component.status.green()); - } else if component.status == "degraded_performance" { - println!("{}: {}", component.name, component.status.yellow()); - } else if component.status == "partial_outage" { - println!( - "{}: {}", - component.name, - component.status.truecolor(255, 165, 0) - ); - } else if component.status == "major_outage" { - println!("{}: {}", component.name, component.status.red()); + Ok(result) + } + + pub fn print() { + let summary = SummaryInfo::get_summary(); + + match summary { + Ok(s) => { + if s.status.indicator == "none" { + println!("{}", s.status.description.green()); + } else if s.status.indicator == "minor" { + println!("{}", s.status.description.yellow()); + } else if s.status.indicator == "major" { + println!("{}", s.status.description.truecolor(255, 165, 0)); + } else if s.status.indicator == "critical" { + println!("{}", s.status.description.red()); } else { + println!("{}", s.status.description); } - } - } - println!(); - if let Some(updated_at) = summary.page.updated_at { - println!("Last Updated At: {}", updated_at); - } - println!("More info: {}", summary.page.url); + println!(); - Ok(()) + for component in s.components { + if component.description.is_some() { + if component.status == "operational" { + println!("{}: {}", component.name, component.status.green()); + } else if component.status == "degraded_performance" { + println!("{}: {}", component.name, component.status.yellow()); + } else if component.status == "partial_outage" { + println!( + "{}: {}", + component.name, + component.status.truecolor(255, 165, 0) + ); + } else if component.status == "major_outage" { + println!("{}: {}", component.name, component.status.red()); + } else { + } + } + } + + println!(); + if let Some(updated_at) = s.page.updated_at { + println!("Last Updated At: {}", updated_at); + } + println!("More info: {}", s.page.url); + } + _ => println!("{}", "Error retrieving information".red()), + }; } } #[derive(Deserialize, Debug)] -pub struct UnresolvedInfo { +pub struct IncidentInfo { pub page: Page, pub incidents: Vec, } -impl UnresolvedInfo { - pub fn print() -> Result<()> { - let status = get_unresolved()?; +impl IncidentInfo { + fn get_incidents(incident_type: IncidentType) -> Result { + let result: IncidentInfo; + + match incident_type { + IncidentType::ALL => { + result = + reqwest::blocking::get("https://www.githubstatus.com/api/v2/incidents.json")? + .json::()?; + } + IncidentType::UNRESOLVED => { + result = reqwest::blocking::get( + "https://www.githubstatus.com/api/v2/incidents/unresolved.json", + )? + .json::()?; + } + } + + Ok(result) + } - if status.incidents.is_empty() { + fn print(self: Self) { + if self.incidents.is_empty() { println!("No unresolved incidents reported"); println!(); } else { - for incident in status.incidents { + for incident in self.incidents { if incident.impact == "none" { println!("{}", incident.name.green()); } else if incident.impact == "minor" { @@ -227,20 +281,26 @@ impl UnresolvedInfo { println!("{}", incident.name); } - println!(" Created At: {}", incident.create_at); + if let Some(created_at) = incident.created_at { + println!(" Created At: {}", created_at); + } println!(" Short Link: {}", incident.shortlink); println!(" Status: {}", incident.status); if let Some(updated_at) = incident.updated_at { println!(" Updated At: {}", updated_at); } - println!(" Updates:"); - for update in incident.incedent_updates { - println!(" Update: {}", update.body); - println!(" create_at: {}", update.created_at); - println!(" status: {}", update.status); - if let Some(updated_at) = update.updated_at { - println!(" Updated At: {}", updated_at); + if let Some(incedent_updates) = incident.incedent_updates { + println!(" Updates:"); + for update in incedent_updates { + println!(" Update: {}", update.body); + if let Some(created_at) = update.created_at { + println!(" created_at: {}", created_at); + } + println!(" status: {}", update.status); + if let Some(updated_at) = update.updated_at { + println!(" Updated At: {}", updated_at); + } } } @@ -248,40 +308,27 @@ impl UnresolvedInfo { } } - if let Some(updated_at) = status.page.updated_at { + if let Some(updated_at) = self.page.updated_at { println!("Last update: {}", updated_at); } - println!("More info: {}", status.page.url); - - Ok(()) + println!("More info: {}", self.page.url); } -} - -fn get_component_status() -> Result { - let result = reqwest::blocking::get("https://www.githubstatus.com/api/v2/components.json")? - .json::()?; - - Ok(result) -} - -fn get_status() -> Result { - let result = reqwest::blocking::get("https://www.githubstatus.com/api/v2/status.json")? - .json::()?; - Ok(result) -} - -fn get_summary() -> Result { - let result = reqwest::blocking::get("https://www.githubstatus.com/api/v2/summary.json")? - .json::()?; + pub fn print_all() { + let info = IncidentInfo::get_incidents(IncidentType::ALL); - Ok(result) -} + match info { + Ok(i) => IncidentInfo::print(i), + _ => println!("{}", "Error retrieving information".red()), + } + } -fn get_unresolved() -> Result { - let result = - reqwest::blocking::get("https://www.githubstatus.com/api/v2/incidents/unresolved.json")? - .json::()?; + pub fn print_unresolved() { + let info = IncidentInfo::get_incidents(IncidentType::UNRESOLVED); - Ok(result) + match info { + Ok(i) => IncidentInfo::print(i), + _ => println!("{}", "Error retrieving information".red()), + } + } } diff --git a/src/main.rs b/src/main.rs index 0c636a0..856266f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ mod github_api; mod options; -use crate::github_api::{ComponentInfo, StatusInfo, SummaryInfo, UnresolvedInfo}; +use crate::github_api::{ComponentInfo, IncidentInfo, StatusInfo, SummaryInfo}; use crate::options::{Command, Options}; use clap::Parser; @@ -10,9 +10,10 @@ fn main() { let opt = Options::parse(); match opt.command { - Command::Summary => SummaryInfo::print().unwrap(), - Command::Status => StatusInfo::print().unwrap(), - Command::Component => ComponentInfo::print().unwrap(), - Command::Unresolved => UnresolvedInfo::print().unwrap(), + Command::AllIncidents => IncidentInfo::print_all(), + Command::Summary => SummaryInfo::print(), + Command::Status => StatusInfo::print(), + Command::Component => ComponentInfo::print(), + Command::UnresolvedIncidents => IncidentInfo::print_unresolved(), } } diff --git a/src/options.rs b/src/options.rs index cd50322..c4eba8d 100644 --- a/src/options.rs +++ b/src/options.rs @@ -9,15 +9,18 @@ pub struct Options { #[derive(Debug, Subcommand)] pub enum Command { - /// Get a summary for the current GitHub status. - Summary, + /// Gets a list of all incidents. + AllIncidents, + + /// Status of each component. + Component, /// Get the current status Status, - /// Status of each component. - Component, + /// Get a summary for the current GitHub status. + Summary, /// Gets a list of any unresolved incidents. - Unresolved, + UnresolvedIncidents, }