Lines
76.36 %
Functions
20.83 %
Branches
100 %
use crate::error::{Error, Result};
use serde::Deserialize;
use std::path::Path;
pub(crate) fn load_from_json<T: for<'a> Deserialize<'a>, P: AsRef<Path>>(path: P) -> Result<T> {
let path = path.as_ref().canonicalize().map_err(|e| Error::Io {
source: e,
path: path.as_ref().to_owned(),
})?;
let bytes = std::fs::read(&path).map_err(|e| Error::Io {
path: path.clone(),
serde_json::from_slice(&bytes).map_err(|e| Error::Serde {
path: Some(path),
})
}
// check the provided values for a website for sanity
pub(crate) fn check_websites(value: &str) -> bool {
for v in value.split_whitespace() {
let url = match url::Url::parse(v) {
Ok(url) => url,
Err(_) => match url::Url::parse(&format!("https://{}", v)) {
Err(_) => return false,
},
};
match url.host() {
Some(url::Host::Domain(host)) => {
// the hostname should have a dot (.) to be useful
if !host.contains('.') {
return false;
Some(url::Host::Ipv4(ip)) => {
if ip.is_private()
|| ip.is_link_local()
|| ip.is_loopback()
|| ip.is_multicast()
|| ip.is_documentation()
|| ip.is_unspecified()
{
Some(url::Host::Ipv6(ip)) => {
if ip.is_loopback() || ip.is_multicast() || ip.is_unspecified() {
None => {
true
#[test]
fn test_check_websites() {
assert!(check_websites(""));
assert!(check_websites("https://nlnet.nl"));
assert!(check_websites("https://nlnet.nl\tros.nl"));
assert!(check_websites("nlnet.nl"));
assert!(!check_websites("YbxuoyIq"));
assert!(!check_websites("127.0.0.1"));
assert!(!check_websites("0.0.0.0"));
assert!(!check_websites("10.0.0.1"));
assert!(!check_websites("169.254.10.65"));
assert!(!check_websites("224.254.10.65"));