use std::fmt::Display;
use crate::shacl_vocab::{
sh_target_class, sh_target_node, sh_target_objects_of, sh_target_subjects_of,
};
use prefixmap::IriRef;
use srdf::{BuildRDF, RDFNode, Rdf, rdf_type, rdfs_class};
#[derive(Debug)]
pub enum Target<S: Rdf>
where
S::Term: Clone,
{
TargetNode(RDFNode), TargetClass(RDFNode),
TargetSubjectsOf(IriRef),
TargetObjectsOf(IriRef),
TargetImplicitClass(RDFNode),
WrongTargetNode(S::Term),
WrongTargetClass(S::Term),
WrongSubjectsOf(S::Term),
WrongObjectsOf(S::Term),
WrongImplicitClass(S::Term),
}
impl<S: Rdf> Target<S> {
pub fn target_node(node: RDFNode) -> Self {
Target::TargetNode(node)
}
pub fn target_class(node: RDFNode) -> Self {
Target::TargetClass(node)
}
pub fn target_subjects_of(iri_ref: IriRef) -> Self {
Target::TargetSubjectsOf(iri_ref)
}
pub fn target_objects_of(iri_ref: IriRef) -> Self {
Target::TargetObjectsOf(iri_ref)
}
pub fn target_implicit_class(node: RDFNode) -> Self {
Target::TargetImplicitClass(node)
}
pub fn write<RDF>(&self, rdf_node: &RDFNode, rdf: &mut RDF) -> Result<(), RDF::Err>
where
RDF: BuildRDF,
{
let node: RDF::Subject = rdf_node.clone().try_into().map_err(|_| unreachable!())?;
match self {
Target::TargetNode(target_rdf_node) => {
rdf.add_triple(node, sh_target_node().clone(), target_rdf_node.clone())
}
Target::TargetClass(node_class) => {
rdf.add_triple(node, sh_target_class().clone(), node_class.clone())
}
Target::TargetSubjectsOf(iri_ref) => rdf.add_triple(
node,
sh_target_subjects_of().clone(),
iri_ref.get_iri().unwrap().clone(),
),
Target::TargetObjectsOf(iri_ref) => rdf.add_triple(
node,
sh_target_objects_of().clone(),
iri_ref.get_iri().unwrap().clone(),
),
Target::TargetImplicitClass(_class) => {
rdf.add_triple(node, rdf_type().clone(), rdfs_class().clone())
}
Target::WrongTargetNode(_) => todo!(),
Target::WrongTargetClass(_) => todo!(),
Target::WrongSubjectsOf(_) => todo!(),
Target::WrongObjectsOf(_) => todo!(),
Target::WrongImplicitClass(_) => todo!(),
}
}
}
impl<S: Rdf> Display for Target<S> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Target::TargetNode(node) => write!(f, "targetNode({node})"),
Target::TargetClass(node) => write!(f, "targetClass({node})"),
Target::TargetSubjectsOf(node) => write!(f, "targetSubjectsOf({node})"),
Target::TargetObjectsOf(node) => write!(f, "targetObjectsOf({node})"),
Target::TargetImplicitClass(node) => write!(f, "targetImplicitClass({node})"),
Target::WrongTargetNode(node) => write!(f, "targetNode({node})"),
Target::WrongTargetClass(node) => write!(f, "targetClass({node})"),
Target::WrongSubjectsOf(node) => write!(f, "targetSubjectsOf({node})"),
Target::WrongObjectsOf(node) => write!(f, "targetObjectsOf({node})"),
Target::WrongImplicitClass(node) => write!(f, "targetImplicitClass({node})"),
}
}
}
impl<RDF: Rdf> Clone for Target<RDF> {
fn clone(&self) -> Self {
match self {
Self::TargetNode(arg0) => Self::TargetNode(arg0.clone()),
Self::TargetClass(arg0) => Self::TargetClass(arg0.clone()),
Self::TargetSubjectsOf(arg0) => Self::TargetSubjectsOf(arg0.clone()),
Self::TargetObjectsOf(arg0) => Self::TargetObjectsOf(arg0.clone()),
Self::TargetImplicitClass(arg0) => Self::TargetImplicitClass(arg0.clone()),
Self::WrongTargetNode(arg0) => Self::WrongTargetNode(arg0.clone()),
Self::WrongTargetClass(arg0) => Self::WrongTargetClass(arg0.clone()),
Self::WrongSubjectsOf(arg0) => Self::WrongSubjectsOf(arg0.clone()),
Self::WrongObjectsOf(arg0) => Self::WrongObjectsOf(arg0.clone()),
Self::WrongImplicitClass(arg0) => Self::WrongImplicitClass(arg0.clone()),
}
}
}
impl<RDF: Rdf> PartialEq for Target<RDF> {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::TargetNode(l0), Self::TargetNode(r0)) => l0 == r0,
(Self::TargetClass(l0), Self::TargetClass(r0)) => l0 == r0,
(Self::TargetSubjectsOf(l0), Self::TargetSubjectsOf(r0)) => l0 == r0,
(Self::TargetObjectsOf(l0), Self::TargetObjectsOf(r0)) => l0 == r0,
(Self::TargetImplicitClass(l0), Self::TargetImplicitClass(r0)) => l0 == r0,
(Self::WrongTargetNode(l0), Self::WrongTargetNode(r0)) => l0 == r0,
(Self::WrongTargetClass(l0), Self::WrongTargetClass(r0)) => l0 == r0,
(Self::WrongSubjectsOf(l0), Self::WrongSubjectsOf(r0)) => l0 == r0,
(Self::WrongObjectsOf(l0), Self::WrongObjectsOf(r0)) => l0 == r0,
(Self::WrongImplicitClass(l0), Self::WrongImplicitClass(r0)) => l0 == r0,
_ => false,
}
}
}