use alloc::string::String;
use borrow_or_share::{BorrowOrShare, Bos};
use super::parts::{Constraints, Meta, Parse, RiMaybeRef, RmrRef};
use crate::component::{IAuthority, Scheme};
use crate::error::IriParseError;
use crate::imp::iri::Iri;
use crate::pct_enc::EStr;
use crate::pct_enc::encoder::{IFragment, IPath, IQuery};
use crate::resolve::{self, ResolveError};
#[derive(Clone, Copy)]
pub struct IriRef<T> {
pub(crate) val: T,
pub(crate) meta: Meta,
}
impl<T> RiMaybeRef for IriRef<T> {
type Val = T;
type WithVal<U> = IriRef<U>;
const CONSTRAINTS: Constraints = Constraints {
scheme_required: false,
};
fn new(val: T, meta: Meta) -> Self {
Self { val, meta }
}
fn make_ref<'i, 'o>(&'i self) -> RmrRef<'o, 'i>
where
T: BorrowOrShare<'i, 'o, str>,
{
RmrRef::new(self.as_str(), &self.meta)
}
}
impl<'a> IriRef<&'a str> {
pub fn parse(input: &'a str) -> Result<Self, IriParseError> {
input.parse_iri()
}
}
impl IriRef<String> {
pub fn parse_owned(input: String) -> Result<Self, (IriParseError, String)> {
input.parse_iri()
}
}
impl IriRef<String> {
#[allow(clippy::should_implement_trait)]
#[inline]
#[must_use]
pub fn borrow(&self) -> IriRef<&str> {
IriRef {
val: &self.val,
meta: self.meta,
}
}
#[inline]
#[must_use]
pub fn into_string(self) -> String {
self.val
}
}
impl IriRef<&str> {
#[inline]
#[must_use]
pub fn to_owned(&self) -> IriRef<String> {
IriRef {
val: self.val.to_owned(),
meta: self.meta,
}
}
}
impl<'i, 'o, T: BorrowOrShare<'i, 'o, str>> IriRef<T> {
#[must_use]
pub fn as_str(&'i self) -> &'o str {
self.val.borrow_or_share()
}
#[must_use]
pub(crate) fn scheme(&'i self) -> Option<&'o Scheme> {
self.make_ref().scheme_opt()
}
#[must_use]
pub(crate) fn authority(&'i self) -> Option<IAuthority<'o>> {
self.make_ref().authority()
}
#[must_use]
pub(crate) fn path(&'i self) -> &'o EStr<IPath> {
self.make_ref().path()
}
#[must_use]
pub(crate) fn query(&'i self) -> Option<&'o EStr<IQuery>> {
self.make_ref().query()
}
#[must_use]
pub(crate) fn fragment(&'i self) -> Option<&'o EStr<IFragment>> {
self.make_ref().fragment()
}
}
impl<T: Bos<str>> IriRef<T> {
pub fn resolve_against<U: Bos<str>>(&self, base: &Iri<U>) -> Result<Iri<String>, ResolveError> {
resolve::resolve(base.make_ref(), self.make_ref(), true).map(RiMaybeRef::from_pair)
}
#[must_use]
pub fn has_scheme(&self) -> bool {
self.make_ref().has_scheme()
}
}