use super::Iri;
use crate::{Literal, MownTerm, TTerm, Term, TermData};
use mownstr::MownStr;
use sophia_iri::resolve::*;
impl<'a, 'b> Resolve<Iri<&'a str>, Iri<MownStr<'a>>> for IriParsed<'b> {
fn resolve(&self, other: Iri<&'a str>) -> Iri<MownStr<'a>> {
if other.is_absolute() {
return other.map_into();
}
let mut buffer = String::new();
let parsed = other.parse_components(&mut buffer);
let joined = self.join(&parsed);
Iri::new_unchecked(joined.to_string())
}
}
impl<'a, 'b, TD> Resolve<&'a Iri<TD>, Iri<MownStr<'a>>> for IriParsed<'b>
where
TD: TermData,
{
fn resolve(&self, other: &'a Iri<TD>) -> Iri<MownStr<'a>> {
self.resolve(other.as_ref_str())
}
}
impl<'a, 'b, TD> Resolve<&'a Literal<TD>, Literal<MownStr<'a>>> for IriParsed<'b>
where
TD: TermData,
{
fn resolve(&self, other: &'a Literal<TD>) -> Literal<MownStr<'a>> {
if other.is_absolute() {
other.clone_into()
} else {
Literal::new_dt(other.txt().as_ref(), self.resolve(other.dt()))
}
}
}
impl<'a, 'b, TD> Resolve<&'a Term<TD>, MownTerm<'a>> for IriParsed<'b>
where
TD: TermData,
{
fn resolve(&self, other: &'a Term<TD>) -> MownTerm<'a> {
match other {
Term::Iri(iri) => Resolve::<_, Iri<MownStr>>::resolve(self, iri).into(),
Term::Literal(lit) => Resolve::<_, Literal<MownStr>>::resolve(self, lit).into(),
term => term.clone_into(),
}
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::{RefTerm, TTerm};
use sophia_iri::test::RELATIVE_IRIS;
#[test]
fn resolve_namespace() {
let base = IriParsed::new("http://a/b/c/d;p?q").unwrap();
for (rel, abs) in RELATIVE_IRIS {
let rel = sophia_api::ns::Namespace::<&str>::new(*rel).unwrap();
let got = base.resolve(&rel);
assert_eq!(&got.as_ref(), abs);
}
}
#[test]
fn resolve_iri() {
let base = IriParsed::new("http://a/b/c/d;p?q").unwrap();
for (rel, abs) in RELATIVE_IRIS {
let rel = Iri::<&str>::new(*rel).unwrap();
let got = base.resolve(&rel);
assert_eq!(&got.value(), abs);
}
}
#[test]
fn resolve_literal() {
let base = IriParsed::new("http://a/b/c/d;p?q").unwrap();
for (rel, abs) in RELATIVE_IRIS {
let rel = Iri::<&str>::new(*rel).unwrap();
let lit = Literal::<&str>::new_dt("hello", rel);
let got = base.resolve(&lit);
assert_eq!(&got.dt().value(), abs);
}
}
#[test]
fn resolve_iri_term() {
let base = IriParsed::new("http://a/b/c/d;p?q").unwrap();
for (rel, abs) in RELATIVE_IRIS {
let rel = RefTerm::new_iri(*rel).unwrap();
let got = base.resolve(&rel);
assert_eq!(&got.value(), abs);
}
}
}