use std::sync::Arc;
use iref::{IriBuf, IriRefBuf};
use list::GraphList;
use minijinja::Value;
use taganak_core::{
graphs::{Graph, GraphView},
terms::{Term, TermError},
};
use taganak_orm::re::PrefixMap;
use tokio::runtime::Handle;
use tracing::trace;
pub(crate) mod list;
pub(crate) mod object;
pub use object::GraphObject;
use crate::{Params, ParamsWithEnv};
pub(crate) fn term_to_value<G>(params: ParamsWithEnv<'static, G>, term: &Arc<Term>) -> Option<Value>
where
G: Graph + std::fmt::Debug + Sync + 'static,
{
trace!(?term, "Resolving term to value");
match &*term.clone() {
Term::Literal(literal) => {
trace!(?term, "is a literal");
Some(Value::from(literal.lexical()))
}
node @ Term::NamedNode(_) | node @ Term::BlankNode(_) => {
trace!(?term, "is a reference");
let handle = Handle::current();
if handle
.block_on(async {
let graph = params.graph.read().unwrap();
graph
.view()
.await
.object(
Some(node),
Some(
&"<http://www.w3.org/1999/02/22-rdf-syntax-ns#first>"
.try_into()
.expect("static IRI"),
),
)
.await
})
.ok()?
.is_some()
{
trace!(?term, "points to a list");
Some(Value::from_object(GraphList::new(
params.base(Some(term.clone())),
)))
} else {
trace!(?term, "points to an object");
Some(Value::from_object(GraphObject::new(
params.base(Some(term.clone())).to_params(),
)))
}
}
_ => None,
}
}
pub(crate) fn str_to_term<G>(params: Params<'_, G>, value: &str) -> Result<Term, TermError> {
if value.starts_with('<') && value.ends_with('>') {
let mut chars = value.chars();
chars.next();
chars.next_back();
if let Some(base) = params.base {
let iri_ref = IriRefBuf::new(chars.as_str().to_string()).unwrap();
Ok(Term::NamedNode(
iri_ref.into_resolved(&base.to_iri().unwrap()),
))
} else {
Ok(Term::NamedNode(
IriBuf::new(chars.as_str().to_string())
.map_err(|_| TermError::UnexpectedValue(value.to_string()))?,
))
}
} else if value.contains(':') && !value.starts_with('_') {
Ok(params.prefix_map.resolve(value).unwrap().as_ref().clone())
} else {
value.try_into()
}
}