#![allow(clippy::module_name_repetitions)]
use crate::error::{Error as IriError, ErrorKind, Result as IriResult};
use crate::Normalize;
use crate::{parse, ValidateStr};
use std::fmt::{Display, Formatter};
use std::hash::{Hash, Hasher};
use std::str::FromStr;
#[derive(Clone, Debug, Eq)]
pub struct Scheme(String);
impl PartialEq for Scheme {
fn eq(&self, other: &Self) -> bool {
self.0.to_lowercase() == other.0.to_lowercase()
}
}
impl Hash for Scheme {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.to_lowercase().hash(state);
}
}
impl Display for Scheme {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}:", self.0)
}
}
impl FromStr for Scheme {
type Err = IriError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if Self::is_valid(s) {
Ok(Self(s.to_string()))
} else {
Err(ErrorKind::ParseSchemeError(s.to_string()).into())
}
}
}
impl ValidateStr for Scheme {
fn is_valid(s: &str) -> bool {
parse::is_scheme(s)
}
}
impl Normalize for Scheme {
fn normalize(self) -> IriResult<Self> {
Ok(Self(self.0.to_lowercase()))
}
}
impl Scheme {
pub fn aaa() -> Self {
"aaa".parse().unwrap()
}
pub fn aaas() -> Self {
"aaas".parse().unwrap()
}
pub fn about() -> Self {
"about".parse().unwrap()
}
pub fn acap() -> Self {
"acap".parse().unwrap()
}
pub fn acct() -> Self {
"acct".parse().unwrap()
}
pub fn cap() -> Self {
"cap".parse().unwrap()
}
pub fn cid() -> Self {
"cid".parse().unwrap()
}
pub fn coap() -> Self {
"coap".parse().unwrap()
}
pub fn coaps() -> Self {
"coaps".parse().unwrap()
}
pub fn crid() -> Self {
"crid".parse().unwrap()
}
pub fn data() -> Self {
"data".parse().unwrap()
}
pub fn dav() -> Self {
"dav".parse().unwrap()
}
pub fn dict() -> Self {
"dict".parse().unwrap()
}
pub fn dns() -> Self {
"dns".parse().unwrap()
}
pub fn example() -> Self {
"example".parse().unwrap()
}
pub fn file() -> Self {
"file".parse().unwrap()
}
pub fn ftp() -> Self {
"ftp".parse().unwrap()
}
pub fn geo() -> Self {
"geo".parse().unwrap()
}
pub fn go() -> Self {
"go".parse().unwrap()
}
pub fn gopher() -> Self {
"gopher".parse().unwrap()
}
pub fn http() -> Self {
"http".parse().unwrap()
}
pub fn https() -> Self {
"https".parse().unwrap()
}
pub fn iax() -> Self {
"iax".parse().unwrap()
}
pub fn icap() -> Self {
"icap".parse().unwrap()
}
pub fn im() -> Self {
"im".parse().unwrap()
}
pub fn imap() -> Self {
"imap".parse().unwrap()
}
pub fn info() -> Self {
"info".parse().unwrap()
}
pub fn ipp() -> Self {
"ipp".parse().unwrap()
}
pub fn ipps() -> Self {
"ipps".parse().unwrap()
}
pub fn iris() -> Self {
"iris".parse().unwrap()
}
pub fn iris_beep() -> Self {
"iris.beep".parse().unwrap()
}
pub fn iris_xpc() -> Self {
"iris.xpc".parse().unwrap()
}
pub fn iris_xpcs() -> Self {
"iris.xpcs".parse().unwrap()
}
pub fn iris_lws() -> Self {
"iris.lws".parse().unwrap()
}
pub fn ldap() -> Self {
"ldap".parse().unwrap()
}
pub fn mailto() -> Self {
"mailto".parse().unwrap()
}
pub fn mid() -> Self {
"mid".parse().unwrap()
}
pub fn msrp() -> Self {
"msrp".parse().unwrap()
}
pub fn msrps() -> Self {
"msrps".parse().unwrap()
}
pub fn mtqp() -> Self {
"mtqp".parse().unwrap()
}
pub fn mupdate() -> Self {
"mupdate".parse().unwrap()
}
pub fn news() -> Self {
"news".parse().unwrap()
}
pub fn nfs() -> Self {
"nfs".parse().unwrap()
}
pub fn ni() -> Self {
"ni".parse().unwrap()
}
pub fn nih() -> Self {
"nih".parse().unwrap()
}
pub fn nntp() -> Self {
"nntp".parse().unwrap()
}
pub fn opaque_lock_token() -> Self {
"opaquelocktoken".parse().unwrap()
}
pub fn pkcs11() -> Self {
"pkcs11".parse().unwrap()
}
pub fn pop() -> Self {
"pop".parse().unwrap()
}
pub fn pres() -> Self {
"pres".parse().unwrap()
}
pub fn reload() -> Self {
"reload".parse().unwrap()
}
pub fn rtsp() -> Self {
"rtsp".parse().unwrap()
}
pub fn service() -> Self {
"service".parse().unwrap()
}
pub fn session() -> Self {
"session".parse().unwrap()
}
pub fn shttp() -> Self {
"shhtp".parse().unwrap()
}
pub fn sieve() -> Self {
"sieve".parse().unwrap()
}
pub fn sip() -> Self {
"sip".parse().unwrap()
}
pub fn sips() -> Self {
"sips".parse().unwrap()
}
pub fn sms() -> Self {
"sms".parse().unwrap()
}
pub fn snmp() -> Self {
"snmp".parse().unwrap()
}
pub fn soap_beep() -> Self {
"soap.beep".parse().unwrap()
}
pub fn soap_beeps() -> Self {
"soap.beeps".parse().unwrap()
}
pub fn stun() -> Self {
"stun".parse().unwrap()
}
pub fn stuns() -> Self {
"stuns".parse().unwrap()
}
pub fn tag() -> Self {
"tag".parse().unwrap()
}
pub fn tel() -> Self {
"tel".parse().unwrap()
}
pub fn telnet() -> Self {
"telnet".parse().unwrap()
}
pub fn tftp() -> Self {
"tftp".parse().unwrap()
}
pub fn this_message() -> Self {
"thismessage".parse().unwrap()
}
pub fn tn3270() -> Self {
"tn3270".parse().unwrap()
}
pub fn tip() -> Self {
"tip".parse().unwrap()
}
pub fn turn() -> Self {
"turn".parse().unwrap()
}
pub fn turns() -> Self {
"turns".parse().unwrap()
}
pub fn tv() -> Self {
"tv".parse().unwrap()
}
pub fn urn() -> Self {
"urn".parse().unwrap()
}
pub fn vemmi() -> Self {
"vemmi".parse().unwrap()
}
pub fn vnc() -> Self {
"vnc".parse().unwrap()
}
pub fn ws() -> Self {
"ws".parse().unwrap()
}
pub fn wss() -> Self {
"wss".parse().unwrap()
}
pub fn xcon() -> Self {
"xcon".parse().unwrap()
}
pub fn xcon_user_id() -> Self {
"xcon-userid".parse().unwrap()
}
pub fn xml_rpc_beep() -> Self {
"xmlrpc.beep".parse().unwrap()
}
pub fn xml_rpc_beeps() -> Self {
"xmlrpc.beeps".parse().unwrap()
}
pub fn xmpp() -> Self {
"xmpp".parse().unwrap()
}
pub fn z3950r() -> Self {
"z39.50r".parse().unwrap()
}
pub fn z3950s() -> Self {
"z39.50s".parse().unwrap()
}
pub fn value(&self) -> &String {
&self.0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_examples() {
assert!(Scheme::from_str("aaa").is_ok());
assert!(Scheme::from_str("tn3270").is_ok());
assert!(Scheme::from_str("iris.beep").is_ok());
assert!(Scheme::from_str("xcon-userid").is_ok());
}
#[test]
fn test_display_examples() {
assert_eq!(
Scheme::from_str("aaa").unwrap().to_string(),
"aaa:".to_string()
);
assert_eq!(
Scheme::from_str("tn3270").unwrap().to_string(),
"tn3270:".to_string()
);
assert_eq!(
Scheme::from_str("iris.beep").unwrap().to_string(),
"iris.beep:".to_string()
);
assert_eq!(
Scheme::from_str("xcon-userid").unwrap().to_string(),
"xcon-userid:".to_string()
);
}
#[test]
fn test_parse_illegal() {
assert_eq!(Scheme::is_valid(""), false);
assert!(Scheme::from_str("").is_err());
assert_eq!(Scheme::is_valid(" "), false);
assert!(Scheme::from_str("").is_err());
assert_eq!(Scheme::is_valid(" aaa"), false);
assert!(Scheme::from_str("").is_err());
assert_eq!(Scheme::is_valid("aa a"), false);
assert!(Scheme::from_str("").is_err());
assert_eq!(Scheme::is_valid("123"), false);
assert!(Scheme::from_str("123").is_err());
assert_eq!(Scheme::is_valid("123ab"), false);
assert!(Scheme::from_str("123ab").is_err());
assert_eq!(Scheme::is_valid("a!"), false);
assert!(Scheme::from_str("a!").is_err());
}
#[test]
fn test_normalize_examples() {
assert_eq!(
Scheme::from_str("aaa").unwrap().normalize().unwrap(),
Scheme::from_str("aaa").unwrap()
);
assert_eq!(
Scheme::from_str("AAA").unwrap().normalize().unwrap(),
Scheme::from_str("aaa").unwrap()
);
assert_eq!(
Scheme::from_str("aAa").unwrap().normalize().unwrap(),
Scheme::from_str("aaa").unwrap()
);
}
#[test]
fn test_equality() {
assert_eq!(
Scheme::from_str("aaa").unwrap(),
Scheme::from_str("AAA").unwrap()
);
}
}