use std::borrow::Cow;
use std::fmt::{self, Display};
use ext::IntoOwned;
use parse::{Indexed, IndexedStr};
use uri::{Authority, Origin, Error, as_utf8_unchecked};
#[derive(Debug, Clone)]
pub struct Absolute<'a> {
source: Option<Cow<'a, str>>,
scheme: IndexedStr<'a>,
authority: Option<Authority<'a>>,
origin: Option<Origin<'a>>,
}
impl<'a> IntoOwned for Absolute<'a> {
type Owned = Absolute<'static>;
fn into_owned(self) -> Self::Owned {
Absolute {
source: self.source.into_owned(),
scheme: self.scheme.into_owned(),
authority: self.authority.into_owned(),
origin: self.origin.into_owned(),
}
}
}
impl<'a> Absolute<'a> {
#[inline]
pub(crate) unsafe fn raw(
source: Cow<'a, [u8]>,
scheme: Indexed<'a, [u8]>,
authority: Option<Authority<'a>>,
origin: Option<Origin<'a>>,
) -> Absolute<'a> {
Absolute {
source: Some(as_utf8_unchecked(source)),
scheme: scheme.coerce(),
authority: authority,
origin: origin,
}
}
#[cfg(test)]
pub(crate) fn new(
scheme: &'a str,
authority: Option<Authority<'a>>,
origin: Option<Origin<'a>>
) -> Absolute<'a> {
Absolute {
source: None, scheme: scheme.into(), authority, origin
}
}
pub fn parse(string: &'a str) -> Result<Absolute<'a>, Error<'a>> {
::parse::uri::absolute_from_str(string)
}
#[inline(always)]
pub fn scheme(&self) -> &str {
self.scheme.from_cow_source(&self.source)
}
#[inline(always)]
pub fn authority(&self) -> Option<&Authority<'a>> {
self.authority.as_ref()
}
#[inline(always)]
pub fn origin(&self) -> Option<&Origin<'a>> {
self.origin.as_ref()
}
}
impl<'a, 'b> PartialEq<Absolute<'b>> for Absolute<'a> {
fn eq(&self, other: &Absolute<'b>) -> bool {
self.scheme() == other.scheme()
&& self.authority() == other.authority()
&& self.origin() == other.origin()
}
}
impl<'a> Display for Absolute<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.scheme())?;
match self.authority {
Some(ref authority) => write!(f, "://{}", authority)?,
None => write!(f, ":")?
}
if let Some(ref origin) = self.origin {
write!(f, "{}", origin)?;
}
Ok(())
}
}