diff options
Diffstat (limited to 'document_tree/src/url.rs')
| -rw-r--r-- | document_tree/src/url.rs | 104 |
1 files changed, 50 insertions, 54 deletions
diff --git a/document_tree/src/url.rs b/document_tree/src/url.rs index 543f9e5..be320e9 100644 --- a/document_tree/src/url.rs +++ b/document_tree/src/url.rs @@ -1,78 +1,74 @@ use std::fmt; use std::str::FromStr; -use url::{self,ParseError}; use serde_derive::Serialize; - +use url::{self, ParseError}; fn starts_with_scheme(input: &str) -> bool { - let scheme = input.split(':').next().unwrap(); - if scheme == input || scheme.is_empty() { - return false; - } - let mut chars = input.chars(); - // First character. - if !chars.next().unwrap().is_ascii_alphabetic() { - return false; - } - for ch in chars { - if !ch.is_ascii_alphanumeric() && ch != '+' && ch != '-' && ch != '.' { - return false; - } - } - true + let scheme = input.split(':').next().unwrap(); + if scheme == input || scheme.is_empty() { + return false; + } + let mut chars = input.chars(); + // First character. + if !chars.next().unwrap().is_ascii_alphabetic() { + return false; + } + for ch in chars { + if !ch.is_ascii_alphanumeric() && ch != '+' && ch != '-' && ch != '.' { + return false; + } + } + true } /// The string representation of a URL, either absolute or relative, that has /// been verified as a valid URL on construction. -#[derive(Debug,PartialEq,Serialize,Clone)] +#[derive(Debug, PartialEq, Serialize, Clone)] #[serde(transparent)] pub struct Url(String); impl Url { - pub fn parse_absolute(input: &str) -> Result<Self, ParseError> { - Ok(url::Url::parse(input)?.into()) - } - pub fn parse_relative(input: &str) -> Result<Self, ParseError> { - // We're assuming that any scheme through which RsT documents are being - // accessed is a hierarchical scheme, and so we can parse relative to a - // random hierarchical URL. - if input.starts_with('/') || !starts_with_scheme(input) { - // Continue only if the parse succeeded, disregarding its result. - let random_base_url = url::Url::parse("https://a/b").unwrap(); - url::Url::options() - .base_url(Some(&random_base_url)) - .parse(input)?; - Ok(Url(input.into())) - } else { - // If this is a URL at all, it's an absolute one. - // There's no appropriate variant of url::ParseError really. - Err(ParseError::SetHostOnCannotBeABaseUrl) - } - } - pub fn as_str(&self) -> &str { - self.0.as_str() - } + pub fn parse_absolute(input: &str) -> Result<Self, ParseError> { + Ok(url::Url::parse(input)?.into()) + } + pub fn parse_relative(input: &str) -> Result<Self, ParseError> { + // We're assuming that any scheme through which RsT documents are being + // accessed is a hierarchical scheme, and so we can parse relative to a + // random hierarchical URL. + if input.starts_with('/') || !starts_with_scheme(input) { + // Continue only if the parse succeeded, disregarding its result. + let random_base_url = url::Url::parse("https://a/b").unwrap(); + url::Url::options() + .base_url(Some(&random_base_url)) + .parse(input)?; + Ok(Url(input.into())) + } else { + // If this is a URL at all, it's an absolute one. + // There's no appropriate variant of url::ParseError really. + Err(ParseError::SetHostOnCannotBeABaseUrl) + } + } + pub fn as_str(&self) -> &str { + self.0.as_str() + } } impl From<url::Url> for Url { - fn from(url: url::Url) -> Self { - Url(url.into()) - } + fn from(url: url::Url) -> Self { + Url(url.into()) + } } - impl fmt::Display for Url { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.as_str()) - } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.as_str()) + } } - impl FromStr for Url { - type Err = ParseError; - fn from_str(input: &str) -> Result<Self, Self::Err> { - Url::parse_absolute(input) - .or_else(|_| Url::parse_relative(input)) - } + type Err = ParseError; + fn from_str(input: &str) -> Result<Self, Self::Err> { + Url::parse_absolute(input).or_else(|_| Url::parse_relative(input)) + } } |
