use std::io::Read;
use json::{JsonValue, parse};
use regex::Regex;
use crate::error::WikiFeetError;
#[doc(hidden)]
const PATTERN_ROMAN_FEET: &str = r#"\["Country", "Favor longer second toe"\],(.*?\s*\s])"#;
#[doc(hidden)]
const PATTERN_FOOT_TATTOOS: &str = r#"\["Country", "Favor foot tattoos"\],(.*?\s*\s])"#;
#[doc(hidden)]
const PATTERN_PAINTED_TOES: &str = r#"\["Country", "Favor painted toes"\],(.*?\s*\s])"#;
#[doc(hidden)]
const PATTERN_SECRET_FEET_LOVER: &str = r#"\["Country", "Keep it secret"\],(.*?\s*\s])"#;
pub struct WikiFeetCountryStats {
country_name: String
}
#[doc(hidden)]
fn http(url: &str) -> Option<String> {
match reqwest::blocking::get(url.to_string()) {
Ok(mut data) => {
let mut body = String::new();
match data.read_to_string(&mut body) {
Ok(_) => Some(body),
Err(_) => None
}
},
Err(_) => None
}
}
#[doc(hidden)]
fn json(info: Option<String>, key: &str) -> Option<String> {
match info {
Some(info) => {
match country(&info) {
Some(data) => {
match parse(&data) {
Ok(json) => {
if json[key].is_null() {
None
} else {
Some(json[key].to_string())
}
},
Err(_) => None
}
},
None => None
}
},
None => None
}
}
#[doc(hidden)]
fn country(info: &str) -> Option<String> {
match parse(info) {
Ok(data) => {
let ref mut json = JsonValue::new_object();
let mut i = 0;
while i < data["country"].len() {
json[data["country"][i][0].to_string().to_uppercase()] = data["country"][i][1]["f"].to_string().into();
i +=1
}
Some(json.to_string())
},
Err(_) => None
}
}
#[doc(hidden)]
fn roman_feet_info() -> Option<String> {
match http("https://www.wikifeet.com/polls/1") {
Some(data) => {
match Regex::new(PATTERN_ROMAN_FEET) {
Ok(regex) => {
match regex.captures(&data) {
Some(cap) => {
let capture = match cap.get(1) {
Some(data) => data.as_str(),
None => return None
};
Some(format!("{{\"country\":[{}}}", capture))
},
None => None
}
},
Err(_) => None
}
},
None => None
}
}
#[doc(hidden)]
fn foot_tattoos_info() -> Option<String> {
match http("https://www.wikifeet.com/polls/2") {
Some(data) => {
match Regex::new(PATTERN_FOOT_TATTOOS) {
Ok(regex) => {
match regex.captures(&data) {
Some(cap) => {
let capture = match cap.get(1) {
Some(data) => data.as_str(),
None => return None
};
Some(format!("{{\"country\":[{}}}", capture))
},
None => None
}
},
Err(_) => None
}
},
None => None
}
}
#[doc(hidden)]
fn painted_toes_info() -> Option<String> {
match http("https://www.wikifeet.com/polls/3") {
Some(data) => {
match Regex::new(PATTERN_PAINTED_TOES) {
Ok(regex) => {
match regex.captures(&data) {
Some(cap) => {
let capture = match cap.get(1) {
Some(data) => data.as_str(),
None => return None
};
Some(format!("{{\"country\":[{}}}", capture))
},
None => None
}
},
Err(_) => None
}
},
None => None
}
}
#[doc(hidden)]
fn secret_feet_lover_info() -> Option<String> {
match http("https://www.wikifeet.com/polls/4") {
Some(data) => {
match Regex::new(PATTERN_SECRET_FEET_LOVER) {
Ok(regex) => {
match regex.captures(&data) {
Some(cap) => {
let capture = match cap.get(1) {
Some(data) => data.as_str(),
None => return None
};
Some(format!("{{\"country\":[{}}}", capture))
},
None => None
}
},
Err(_) => None
}
},
None => None
}
}
impl WikiFeetCountryStats {
pub fn new(country_name: &str) -> Self {
Self {
country_name: country_name.to_uppercase()
}
}
pub fn roman_feet(&self) -> Result<String, WikiFeetError> {
match json(roman_feet_info(),self.country_name.as_str()) {
Some(data) => {
Ok(data)
},
None => Err(WikiFeetError::Null(String::from("null")))
}
}
pub fn foot_tattoos(&self) -> Result<String, WikiFeetError> {
match json(foot_tattoos_info(),self.country_name.as_str()) {
Some(data) => {
Ok(data)
},
None => Err(WikiFeetError::Null(String::from("null")))
}
}
pub fn painted_toes(&self) -> Result<String, WikiFeetError> {
match json(painted_toes_info(),self.country_name.as_str()) {
Some(data) => {
Ok(data)
},
None => Err(WikiFeetError::Null(String::from("null")))
}
}
pub fn secret_feet_lover(&self) -> Result<String, WikiFeetError> {
match json(secret_feet_lover_info(),self.country_name.as_str()) {
Some(data) => {
Ok(data)
},
None => Err(WikiFeetError::Null(String::from("null")))
}
}
}