use super::team::Team;
use chrono::prelude::*;
use select::document::Document;
use select::predicate::Name;
use serde_derive::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
pub struct Match {
id: String,
datetime: DateTime<Utc>,
map: String,
teams: Vec<Team>,
}
impl Eq for Match {}
impl PartialEq for Match {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
impl Match {
fn new(document: &Document) -> Result<Self, Box<dyn std::error::Error>> {
Ok(Self {
id: Self::get_match_id(document),
teams: Match::get_teams(document),
datetime: Self::popflash_time_to_utc(document)?,
map: Self::get_map_name(document),
})
}
pub async fn from_id(match_id: usize) -> Result<Match, Box<dyn std::error::Error>> {
let body = crate::utility::get_body_from_id(match_id).await?;
Match::new(&body)
}
pub async fn from_url(url: &str) -> Result<Match, Box<dyn std::error::Error>> {
let body = crate::utility::get_body_from_url(url).await?;
Match::new(&body)
}
fn popflash_time_to_utc(
document: &Document,
) -> Result<DateTime<Utc>, Box<dyn std::error::Error>> {
let mut date = document.find(Name("h2")).into_iter().next().unwrap().text();
let mut time = date.clone();
date.replace_range(0..date.find("ON ").unwrap() + 3, "");
date.replace_range(date.find(' ').unwrap().., "");
time.replace_range(0..time.find("AT ").unwrap() + 3, "");
time.replace_range(time.find(' ').unwrap().., "");
let date_iter = date.split('/');
let mut time_iter = time.split(':');
let dates = date_iter.collect::<Vec<_>>();
let datetime = Utc
.ymd(
dates[2].parse::<i32>()?,
dates[0].parse::<u32>()?,
dates[1].parse::<u32>()?,
)
.and_hms(
time_iter.next().unwrap().parse::<u32>()?,
time_iter.next().unwrap().parse::<u32>()?,
time_iter.next().unwrap().parse::<u32>()?,
);
Ok(datetime)
}
fn get_map_name(document: &Document) -> String {
let lines = document.nth(0).unwrap().html();
let new_lines: Vec<String> = lines
.lines()
.collect::<Vec<&str>>()
.into_iter()
.map(|element| element.to_string())
.collect();
let map_name = new_lines
.iter()
.position(|line| line.contains("score score-2"))
.unwrap()
+ 6;
new_lines[map_name].clone()
}
pub fn get_teams(document: &Document) -> Vec<Team> {
let mut teams: Vec<Team> = vec![];
let team1 = Team::new(0, document);
let team2 = Team::new(1, document);
teams.push(team1);
teams.push(team2);
teams
}
fn get_match_id(document: &Document) -> String {
document
.find(Name("title"))
.next()
.unwrap()
.text()
.split_whitespace()
.nth(1)
.unwrap()
.to_string()
}
}
#[cfg(test)]
mod tests {
const EXAMPLE_GAME_URL: &str = "https://popflash.site/match/1281644";
const EXAMPLE_GAME_ID: usize = 1281644;
mod from_id {
use select::document::Document;
use crate::Match;
use super::*;
#[tokio::test]
async fn valid_popflash_id_1() {
assert!(crate::Match::from_id(EXAMPLE_GAME_ID).await.is_ok())
}
}
mod from_url {
}
mod popflash_time_to_utc {
}
}