use fancy_regex::escape as regex_escape;
use rand::distributions::Alphanumeric;
use rand::{thread_rng, Rng};
use std::env;
use std::fs::File;
use std::io;
use std::path::Path;
use urlparse::urlparse;
pub fn fetch_url(
url: &String,
error_message: String,
) -> Result<reqwest::blocking::Response, Box<dyn std::error::Error>> {
let response = reqwest::blocking::get(url)?;
if response.status().is_success() {
Ok(response)
} else {
Err(Box::new(std::io::Error::new(
std::io::ErrorKind::NotFound,
error_message,
)))
}
}
pub fn fetch_file(
url: &String,
destination: &String,
) -> Result<String, Box<dyn std::error::Error>> {
let response = fetch_url(url, String::from("Couldn't reach the remote server."))?;
let body = response.text().expect("Invalid body.");
let mut output_file = File::create(destination).expect("Couldn't create file.");
io::copy(&mut body.as_bytes(), &mut output_file).expect("Couldn't write content.");
Ok(destination.to_string())
}
pub fn download_file(user_input: &String) -> (String, bool) {
if !user_input.contains("://") {
return (user_input.clone(), false);
}
let filename: String = thread_rng()
.sample_iter(&Alphanumeric)
.take(30)
.map(char::from)
.collect();
let temp_file = Path::new(&env::temp_dir().as_os_str()).join(filename);
let tmp_path = temp_file.to_str().unwrap().to_string();
return (fetch_file(user_input, &tmp_path).unwrap_or(tmp_path), true);
}
pub fn to_regex_string(extensions: Result<Vec<String>, Box<dyn std::error::Error>>) -> String {
let result = extensions
.unwrap()
.iter()
.map(|ext| format!(r"((?:\.(?:{})))", regex_escape(ext)))
.collect::<Vec<String>>()
.join("|");
result
}
#[allow(dead_code)]
pub fn extract_netloc(data: &String) -> String {
let parsed_url = urlparse(data);
let mut result;
if parsed_url.netloc.is_empty() && !parsed_url.path.is_empty() {
result = parsed_url.path.as_str()
} else if !parsed_url.netloc.is_empty() {
result = parsed_url.netloc.as_str()
} else {
result = data.as_str()
}
if result.contains("//") {
result = result.split("//").next().unwrap()
}
if result.contains('/') {
result = result.split('/').next().unwrap()
}
result.to_string()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_to_regex_string() {
let given = Ok(vec!["com".to_string(), "google".to_string()]);
let expected = "((?:\\.(?:com)))|((?:\\.(?:google)))".to_string();
assert_eq!(to_regex_string(given), expected)
}
#[test]
fn test_to_regex_string_emtpy_vec() {
let given = Ok(vec![]);
let expected = "".to_string();
assert_eq!(to_regex_string(given), expected)
}
#[test]
fn test_to_regex_string_single_ext_vec() {
let given = Ok(vec!["com".to_string()]);
let expected = "((?:\\.(?:com)))".to_string();
assert_eq!(to_regex_string(given), expected)
}
#[test]
fn test_extract_netloc_empty_str() {
let given = "".to_string();
let expected = "".to_string();
assert_eq!(extract_netloc(&given), expected)
}
#[test]
fn test_extract_netloc_nothing_to_decode() {
let given = "example.org".to_string();
let expected = "example.org".to_string();
assert_eq!(extract_netloc(&given), expected)
}
#[test]
fn test_extract_netloc_full_url() {
let given = "https://example.org/hello/world/this/is/a/test".to_string();
let expected = "example.org".to_string();
assert_eq!(extract_netloc(&given), expected)
}
#[test]
fn test_extract_netloc_full_url_with_port() {
let given = "https://example.org:8080/hello/world/this/is/a/test".to_string();
let expected = "example.org:8080".to_string();
assert_eq!(extract_netloc(&given), expected)
}
#[test]
fn test_extract_netloc_full_url_with_params() {
let given = "https://example.org/?is_admin=true".to_string();
let expected = "example.org".to_string();
assert_eq!(extract_netloc(&given), expected)
}
#[test]
fn test_extract_netloc_url_without_scheme() {
let given = "example.org/hello/world/this/is/a/test".to_string();
let expected = "example.org".to_string();
assert_eq!(extract_netloc(&given), expected)
}
#[test]
fn test_extract_netloc_url_without_scheme_and_with_params() {
let given = "example.org/?is_admin=true".to_string();
let expected = "example.org".to_string();
assert_eq!(extract_netloc(&given), expected)
}
#[test]
fn test_extract_netloc_url_without_protocol() {
let given = "://example.org/hello/world/this/is/a/test".to_string();
let expected = "example.org".to_string();
assert_eq!(extract_netloc(&given), expected)
}
#[test]
fn test_extract_netloc_url_without_protocol_and_with_params() {
let given = "://example.org/?is_admin=true".to_string();
let expected = "example.org".to_string();
assert_eq!(extract_netloc(&given), expected)
}
#[test]
fn test_extract_netloc_url_without_protocol_and_path() {
let given = "://example.org/".to_string();
let expected = "example.org".to_string();
assert_eq!(extract_netloc(&given), expected)
}
#[test]
fn test_extract_netloc_url_startswith_2_slashes() {
let given = "//example.org/hello/world/this/is/a/test".to_string();
let expected = "example.org".to_string();
assert_eq!(extract_netloc(&given), expected)
}
#[test]
fn test_extract_netloc_url_startswith_1_slash() {
let given = "/example.org/hello/world/this/is/a/test".to_string();
let expected = "".to_string();
assert_eq!(extract_netloc(&given), expected)
}
}