#[cfg(feature = "validator")]
pub extern crate validators;
#[cfg(feature = "validator")]
use validators::domain::Domain;
#[cfg(feature = "validator")]
use validators::host::Host;
#[cfg(feature = "validator")]
use validators::ipv4::IPv4;
#[cfg(feature = "validator")]
use validators::ipv6::IPv6;
#[cfg(feature = "validator")]
use validators::http_url::HttpUrlLocalableWithProtocol;
#[cfg(feature = "validator")]
use validators::http_ftp_url::HttpFtpUrlLocalableWithProtocol;
macro_rules! impl_protocol {
( $($protocol:ident, $name:expr, $port:expr), * ) => {
pub enum Protocol{
$(
$protocol,
)+
Custom(String, u16)
}
impl Protocol{
pub fn get_default_from_string(s: String) -> Option<Self>{
let lowered_case = s.to_lowercase();
match lowered_case.as_str() {
$(
$name => Some(Protocol::$protocol),
)+
_ => None
}
}
pub fn get_default_from_str(s: &str) -> Option<Self>{
let lowered_case = s.to_lowercase();
match lowered_case.as_str() {
$(
$name => Some(Protocol::$protocol),
)+
_ => None
}
}
pub fn get_default_port(&self) -> u16 {
match self {
$(
Protocol::$protocol => $port,
)+
Protocol::Custom(_, port) => *port
}
}
pub fn get_name(&self) -> &str {
match self {
$(
Protocol::$protocol => $name,
)+
Protocol::Custom(name, _) => &name
}
}
}
};
}
impl_protocol!(
HTTP, "http", 80,
HTTPS, "https", 443,
FTP, "ftp", 21
);
pub fn create_prefix<S: AsRef<str>, P:AsRef<str>>(protocol: Protocol, domain: S, port: Option<u16>, path: Option<P>) -> String {
let protocol_name = protocol.get_name();
let mut prefix = format!("{}://{}", protocol_name, domain.as_ref());
if let Some(port) = port {
let protocol_port = protocol.get_default_port();
if port != protocol_port {
prefix.push(':');
prefix.push_str(&port.to_string());
}
}
if let Some(path) = path {
let path = path.as_ref();
if !path.starts_with("/") {
prefix.push('/');
}
prefix.push_str(path);
}
prefix
}
#[cfg(feature = "validator")]
pub fn create_prefix_with_validated_domain<P: AsRef<str>>(protocol: Protocol, domain: &Domain, path: Option<P>) -> String {
let port = domain.get_port();
let domain = domain.get_full_domain_without_port();
create_prefix(protocol, domain, port, path)
}
#[cfg(feature = "validator")]
pub fn create_prefix_with_validated_ipv4<P: AsRef<str>>(protocol: Protocol, ipv4: &IPv4, path: Option<P>) -> String {
let port = ipv4.get_port();
let ipv4 = ipv4.get_full_ipv4_without_port();
create_prefix(protocol, ipv4, port, path)
}
#[cfg(feature = "validator")]
pub fn create_prefix_with_validated_ipv6<P: AsRef<str>>(protocol: Protocol, ipv6: &IPv6, path: Option<P>) -> String {
let port = ipv6.get_port();
let ipv6 = ipv6.get_full_ipv6_without_port();
let ipv6 = format!("[{}]", ipv6);
create_prefix(protocol, &ipv6, port, path)
}
#[cfg(feature = "validator")]
pub fn create_prefix_with_validated_host<P: AsRef<str>>(protocol: Protocol, host: &Host, path: Option<P>) -> String {
match host {
Host::Domain(domain) => {
create_prefix_with_validated_domain(protocol, domain, path)
}
Host::IPv4(ipv4) => {
create_prefix_with_validated_ipv4(protocol, ipv4, path)
}
Host::IPv6(ipv6) => {
create_prefix_with_validated_ipv6(protocol, ipv6, path)
}
}
}
#[cfg(feature = "validator")]
pub fn create_prefix_with_validated_http_url(http_url: &HttpUrlLocalableWithProtocol) -> String {
let protocol = if http_url.is_https() {
Protocol::HTTPS
} else {
Protocol::HTTP
};
create_prefix_with_validated_host(protocol, http_url.get_host(), http_url.get_path())
}
#[cfg(feature = "validator")]
pub fn create_prefix_with_validated_http_ftp_url(http_ftp_url: &HttpFtpUrlLocalableWithProtocol) -> String {
let protocol = if http_ftp_url.is_https() {
Protocol::HTTPS
} else if http_ftp_url.is_http() {
Protocol::HTTP
} else {
Protocol::FTP
};
create_prefix_with_validated_host(protocol, http_ftp_url.get_host(), http_ftp_url.get_path())
}