#[cfg(feature = "alloc")]
use alloc::collections::TryReserveError;
#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::string::String;
#[cfg(feature = "alloc")]
use crate::convert::try_percent_encode_iri_inline;
use crate::convert::MappedToUri;
use crate::spec::IriSpec;
use crate::types::{
RiAbsoluteStr, RiFragmentStr, RiQueryStr, RiReferenceStr, RiRelativeStr, RiStr,
};
#[cfg(feature = "alloc")]
use crate::types::{
RiAbsoluteString, RiFragmentString, RiQueryString, RiReferenceString, RiRelativeString,
RiString,
};
use crate::types::{
UriAbsoluteStr, UriFragmentStr, UriQueryStr, UriReferenceStr, UriRelativeStr, UriStr,
};
#[cfg(feature = "alloc")]
use crate::types::{
UriAbsoluteString, UriFragmentString, UriQueryString, UriReferenceString, UriRelativeString,
UriString,
};
pub type IriAbsoluteStr = RiAbsoluteStr<IriSpec>;
#[cfg(feature = "alloc")]
pub type IriAbsoluteString = RiAbsoluteString<IriSpec>;
pub type IriFragmentStr = RiFragmentStr<IriSpec>;
#[cfg(feature = "alloc")]
pub type IriFragmentString = RiFragmentString<IriSpec>;
pub type IriStr = RiStr<IriSpec>;
#[cfg(feature = "alloc")]
pub type IriString = RiString<IriSpec>;
pub type IriReferenceStr = RiReferenceStr<IriSpec>;
#[cfg(feature = "alloc")]
pub type IriReferenceString = RiReferenceString<IriSpec>;
pub type IriRelativeStr = RiRelativeStr<IriSpec>;
#[cfg(feature = "alloc")]
pub type IriRelativeString = RiRelativeString<IriSpec>;
pub type IriQueryStr = RiQueryStr<IriSpec>;
#[cfg(feature = "alloc")]
pub type IriQueryString = RiQueryString<IriSpec>;
macro_rules! impl_conversion_between_uri {
(
$ty_owned_iri:ident,
$ty_owned_uri:ident,
$ty_borrowed_iri:ident,
$ty_borrowed_uri:ident,
$example_iri:expr,
$example_uri:expr
) => {
impl $ty_borrowed_iri {
#[doc = concat!("use iri_string::format::ToDedicatedString;")]
#[doc = concat!("use iri_string::types::{", stringify!($ty_borrowed_iri), ", ", stringify!($ty_owned_uri), "};")]
#[doc = concat!("let iri = ", stringify!($ty_borrowed_iri), "::new(", stringify!($example_iri), ")?;")]
#[doc = concat!("let uri: ", stringify!($ty_owned_uri), " = iri.encode_to_uri().to_dedicated_string();")]
#[doc = concat!("assert_eq!(uri, ", stringify!($example_uri), ");")]
#[inline]
#[must_use]
pub fn encode_to_uri(&self) -> MappedToUri<'_, Self> {
MappedToUri::from(self)
}
#[doc = concat!("`", stringify!($ty_borrowed_uri), "::new(self.as_str()).ok()`.")]
#[doc = concat!("use iri_string::types::{", stringify!($ty_borrowed_iri), ", ", stringify!($ty_borrowed_uri), "};")]
#[doc = concat!("let ascii_iri = ", stringify!($ty_borrowed_iri), "::new(", stringify!($example_uri), ")?;")]
#[doc = concat!(" Some(", stringify!($example_uri), ")")]
#[doc = concat!("let nonascii_iri = ", stringify!($ty_borrowed_iri), "::new(", stringify!($example_iri), ")?;")]
#[must_use]
pub fn as_uri(&self) -> Option<&$ty_borrowed_uri> {
if !self.as_str().is_ascii() {
return None;
}
debug_assert!(
<$ty_borrowed_uri>::new(self.as_str()).is_ok(),
"[consistency] the ASCII-only IRI must also be a valid URI"
);
let uri = unsafe { <$ty_borrowed_uri>::new_maybe_unchecked(self.as_str()) };
Some(uri)
}
}
#[cfg(feature = "alloc")]
impl $ty_owned_iri {
#[doc = concat!("[`encode_to_uri`][`", stringify!($ty_borrowed_iri), "::encode_to_uri`]")]
#[doc = concat!("use iri_string::types::", stringify!($ty_owned_iri), ";")]
#[doc = concat!("let mut iri = ", stringify!($ty_owned_iri), "::try_from(", stringify!($example_iri), ")?;")]
#[doc = concat!("assert_eq!(iri, ", stringify!($example_uri), ");")]
#[inline]
pub fn encode_to_uri_inline(&mut self) {
self.try_encode_to_uri_inline()
.expect("failed to allocate memory");
}
#[doc = concat!("[`encode_to_uri`][`", stringify!($ty_borrowed_iri), "::encode_to_uri`]")]
#[doc = concat!("use iri_string::types::", stringify!($ty_owned_iri), ";")]
#[doc = concat!("let mut iri = ", stringify!($ty_owned_iri), "::try_from(", stringify!($example_iri), ")?;")]
#[doc = concat!("assert_eq!(iri, ", stringify!($example_uri), ");")]
#[inline]
pub fn try_encode_to_uri_inline(&mut self) -> Result<(), TryReserveError> {
unsafe {
let buf = self.as_inner_mut();
try_percent_encode_iri_inline(buf)?;
}
debug_assert!(
<$ty_borrowed_iri>::new(self.as_str()).is_ok(),
"[consistency] the content must be valid at any time"
);
Ok(())
}
#[doc = concat!("[`encode_to_uri`][`", stringify!($ty_borrowed_iri), "::encode_to_uri`]")]
#[doc = concat!("use iri_string::types::{", stringify!($ty_owned_iri), ", ", stringify!($ty_owned_uri), "};")]
#[doc = concat!("let iri = ", stringify!($ty_owned_iri), "::try_from(", stringify!($example_iri), ")?;")]
#[doc = concat!("let uri: ", stringify!($ty_owned_uri), " = iri.encode_into_uri();")]
#[doc = concat!("assert_eq!(uri, ", stringify!($example_uri), ");")]
#[inline]
#[must_use]
pub fn encode_into_uri(self) -> $ty_owned_uri {
self.try_encode_into_uri()
.expect("failed to allocate memory")
}
#[doc = concat!("[`encode_to_uri`][`", stringify!($ty_borrowed_iri), "::encode_to_uri`]")]
#[doc = concat!("use iri_string::types::{", stringify!($ty_owned_iri), ", ", stringify!($ty_owned_uri), "};")]
#[doc = concat!("let iri = ", stringify!($ty_owned_iri), "::try_from(", stringify!($example_iri), ")?;")]
#[doc = concat!("let uri: ", stringify!($ty_owned_uri), " = iri.try_encode_into_uri()")]
#[doc = concat!("assert_eq!(uri, ", stringify!($example_uri), ");")]
pub fn try_encode_into_uri(mut self) -> Result<$ty_owned_uri, TryReserveError> {
self.try_encode_to_uri_inline()?;
let s: String = self.into();
debug_assert!(
<$ty_borrowed_uri>::new(s.as_str()).is_ok(),
"[consistency] the encoded IRI must also be a valid URI"
);
let uri = unsafe { <$ty_owned_uri>::new_maybe_unchecked(s) };
Ok(uri)
}
#[doc = concat!("use iri_string::types::{", stringify!($ty_owned_iri), ", ", stringify!($ty_owned_uri), "};")]
#[doc = concat!("let ascii_iri = ", stringify!($ty_owned_iri), "::try_from(", stringify!($example_uri), ")?;")]
#[doc = concat!(" Ok(", stringify!($example_uri), ".to_string())")]
#[doc = concat!("let nonascii_iri = ", stringify!($ty_owned_iri), "::try_from(", stringify!($example_iri), ")?;")]
#[doc = concat!(" Err(", stringify!($example_iri), ".to_string())")]
pub fn try_into_uri(self) -> Result<$ty_owned_uri, $ty_owned_iri> {
if !self.as_str().is_ascii() {
return Err(self);
}
let s: String = self.into();
debug_assert!(
<$ty_borrowed_uri>::new(s.as_str()).is_ok(),
"[consistency] the ASCII-only IRI must also be a valid URI"
);
let uri = unsafe { <$ty_owned_uri>::new_maybe_unchecked(s) };
Ok(uri)
}
}
};
}
impl_conversion_between_uri!(
IriAbsoluteString,
UriAbsoluteString,
IriAbsoluteStr,
UriAbsoluteStr,
"http://example.com/?alpha=\u{03B1}",
"http://example.com/?alpha=%CE%B1"
);
impl_conversion_between_uri!(
IriReferenceString,
UriReferenceString,
IriReferenceStr,
UriReferenceStr,
"http://example.com/?alpha=\u{03B1}",
"http://example.com/?alpha=%CE%B1"
);
impl_conversion_between_uri!(
IriRelativeString,
UriRelativeString,
IriRelativeStr,
UriRelativeStr,
"../?alpha=\u{03B1}",
"../?alpha=%CE%B1"
);
impl_conversion_between_uri!(
IriString,
UriString,
IriStr,
UriStr,
"http://example.com/?alpha=\u{03B1}",
"http://example.com/?alpha=%CE%B1"
);
impl_conversion_between_uri!(
IriQueryString,
UriQueryString,
IriQueryStr,
UriQueryStr,
"alpha-is-\u{03B1}",
"alpha-is-%CE%B1"
);
impl_conversion_between_uri!(
IriFragmentString,
UriFragmentString,
IriFragmentStr,
UriFragmentStr,
"alpha-is-\u{03B1}",
"alpha-is-%CE%B1"
);